這篇試著將使用 source code break into DLL function .
DLL_fun(int a, int b)
Pseudo code:
push a,
push b,
call DLL_fun
return_addr:
===> 改成
push a
push b
push return_addr
jmp DLL_fun
==========================
整段實驗, 先使用斷點, 停在 DLL_fun(5,3); 這行, 然後按下 CTRL+ALT+D, 進入反組譯. (必要時修改machine code 實驗, call 的行為
然後使用F11, 單步進入DLL_fun 的真正入口.
但我在C# 對ASM 做單步trace, 發現確不是如此. 單純
C# 會以下面的方式調用 DLL 中既有的 function.
宣告:
public static partial class NativeMethods
{
#region user32.dll
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern bool XXX(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, CopyPixelOperation dwRop);
}
==> 以上會產生function call mapping table.
NativeMethods.XXX(a,1, 2, 3, 4, b, 6, 7, d);
00007FFB28A7396B CC int 3
00007FFB28A7396C 44 24 20 and al,20h
00007FFB28A7396F 04 00 add al,0
00007FFB28A73971 00 00 add byte ptr [rax],al
00007FFB28A73973 48 8B 8D 00 01 00 00 mov rcx,qword ptr [rbp+100h]
00007FFB28A7397A 48 89 4C 24 28 mov qword ptr [rsp+28h],rcx
00007FFB28A7397F C7 44 24 30 06 00 00 00 mov dword ptr [rsp+30h],6
00007FFB28A73987 C7 44 24 38 07 00 00 00 mov dword ptr [rsp+38h],7
00007FFB28A7398F 8B 8D FC 00 00 00 mov ecx,dword ptr [rbp+0FCh]
00007FFB28A73995 89 4C 24 40 mov dword ptr [rsp+40h],ecx
00007FFB28A73999 48 8B 8D 08 01 00 00 mov rcx,qword ptr [rbp+108h]
00007FFB28A739A0 BA 01 00 00 00 mov edx,1
00007FFB28A739A5 41 B8 02 00 00 00 mov r8d,2
00007FFB28A739AB 41 B9 03 00 00 00 mov r9d,3
> 00007FFB28A739B1 E8 1A F5 FF FF call ShareX.HelpersLib.NativeMethods.BitBlt(IntPtr, Int32, Int32, Int32, Int32, IntPtr, Int32, Int32, flag) (07FFB28A72ED0h)
在這行按下F11, 會跳到 00007FFBCF113980
而不是 "7FFB28A72ED0" , <-- 這才是assembly 的位置. ==> 顯然debugger 會多做一些事, 或是CPU 透過Interrupt 重新解釋了 "7FFB28A72ED0" 內容及 L_STUB_PInvoke()
因為沒有打算深入了解, L_STUB_PInvoke()
00007FFB28A739B6 0F B6 C8 movzx ecx,al
00007FFB28A739B9 89 8D BC 00 00 00 mov dword ptr [rbp+0BCh],ecx
00007FFB28A739BF 90 nop
=====
E8: call 應會跳到這裡. (以assenbly 解釋)
00007FFB28A72ED0 49 BA B0 03 B3 28 FB 7F 00 00 mov r10,7FFB28B303B0h (像是另一table entry)
00007FFB28A72EDA 40 E9 20 19 00 00 jmp DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, Int32, Int32, Int32, Int32, IntPtr, Int32, Int32, System.Drawing.CopyPixelOperation) (07FFB28A74800h)
所以這7FFB28A72ED0 並不是真正的Bitblt 的進入點
但使用單步 F11 時, 確會直接跳到真正的DLL func 開頭
00007FFBCF113980 48 89 5C 24 08 mov qword ptr [rsp+8],rbx
------
觀察 RSP:
從7FFB28A739B1 進入到 7FFBCF113980, RSP 減少了0xE8
如果使用
push rcx
jmp e9 E8 1A F5 FF FF (00007FFB28A72ED0)
從7FFB28A739B1 進入到 7FFBCF113980, RSP 減少了0x08
好! 就實驗到這裡.
確定實驗無法成功,
目的: 串接 function call 將一半的動作在提前 caller 端做, 然後直接跳到 (entry+N)的位址
除非弄懂 二層以上的calling STUB_PInvoke() 的內容及多push 的0xE0 資料代表的意思.
留下記錄. 以後如果有新想法再回來補充.
---------
000000CA5B5FE910
000000CA5B5F9468
留言列表