Did*_*nov 4 c c++ assembly signature disassembly
在DLL中找到了一个函数地址.没有这个DLL的源代码,不是我的.这个DLL并没有经常更改,但是当更改时,通过反汇编找到它是一个问题.在网上看到一些关于使其签名的注释,然后通过这个保存的签名找到它.您能否就如何实施这一点提出一些想法或工作实例?
您可以通过代码签名扫描来实现这一点,这是我过去所做的.这个概念主要依赖于这样一个事实,即函数在更新之间通常不会发生太大的变化,而只是重新定位,因为它们被其他扩展或缩小的函数向前推或向后推.
让我们举一个例子MessageBoxA,谁的反汇编对我来说是这样的:
765DEA11 > 8BFF MOV EDI,EDI
765DEA13 55 PUSH EBP
765DEA14 8BEC MOV EBP,ESP
765DEA16 833D 749A5E76 00 CMP DWORD PTR DS:[765E9A74],0
765DEA1D 74 24 JE SHORT USER32.765DEA43
765DEA1F 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
765DEA25 6A 00 PUSH 0
765DEA27 FF70 24 PUSH DWORD PTR DS:[EAX+24]
765DEA2A 68 A49E5E76 PUSH USER32.765E9EA4
765DEA2F FF15 34145876 CALL DWORD PTR DS:[<&KERNEL32.Interlocke>; kernel32.InterlockedCompareExchange
765DEA35 85C0 TEST EAX,EAX
765DEA37 75 0A JNZ SHORT USER32.765DEA43
765DEA39 C705 A09E5E76 01>MOV DWORD PTR DS:[765E9EA0],1
765DEA43 6A 00 PUSH 0
765DEA45 FF75 14 PUSH DWORD PTR SS:[EBP+14]
765DEA48 FF75 10 PUSH DWORD PTR SS:[EBP+10]
765DEA4B FF75 0C PUSH DWORD PTR SS:[EBP+C]
765DEA4E FF75 08 PUSH DWORD PTR SS:[EBP+8]
765DEA51 E8 73FFFFFF CALL USER32.MessageBoxExA
765DEA56 5D POP EBP
765DEA57 C2 1000 RETN 10
Run Code Online (Sandbox Code Playgroud)
诀窍是猜测你认为在更新中可能保持不变的某些代码块,但更重要的是这个函数是唯一的.通常,扫描结尾/序言是没用的.我可能会采取以下块:
765DEA16 833D 749A5E76 00 CMP DWORD PTR DS:[765E9A74],0
765DEA1D 74 24 JE SHORT USER32.765DEA43
765DEA1F 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
765DEA25 6A 00 PUSH 0
765DEA27 FF70 24 PUSH DWORD PTR DS:[EAX+24]
765DEA2A 68 A49E5E76 PUSH USER32.765E9EA4
765DEA2F FF15 34145876 CALL DWORD PTR DS:[<&KERNEL32.Interlocke>;
Run Code Online (Sandbox Code Playgroud)
选择块的长度时必须保持平衡.块越长,唯一标识函数的可能性越大,但更新期间插入某些代码的可能性越大,这意味着它被拆分等等.请注意,我选择的块有多个内存引用.我们不能依赖任何数据或函数地址,因为这些地址可能会在下次更新时重新定位,因此我们使用通配符填充这些字节:
765DEA16 833D XXXXXXXX 00 CMP DWORD PTR DS:[XXXXXXXX],0
765DEA1D 74 XX JE SHORT XXXXXXXX
765DEA1F 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
765DEA25 6A 00 PUSH 0
765DEA27 FF70 24 PUSH DWORD PTR DS:[EAX+24]
765DEA2A 68 XXXXXXXX PUSH XXXXXXXX
765DEA2F FF15 XXXXXXXX CALL DWORD PTR DS:[XXXXXXXX]
Run Code Online (Sandbox Code Playgroud)
这意味着我们的字节签名现在是:
0x83 0x3D 0x?0X?0X?0X?0x74 0x?0x64 0xA1 0x18 0x00 0x00 0x00 0x6A 0x00 0xFF 0x70 0x24 0x68 0x?0X?0X?0X?0xFF 0x15 0x?0X?0X?0X?
该0x?字节表示通配符这是我们希望改变字节.其他的是我们期望在更新中不会改变的字节.要使用字节在运行时定位函数,您需要扫描这些字节(考虑通配符).这个过程大致如下:
VirtualQueryEx)for跳过通配符字节的循环)0x765DEA16 - 0x765DEA11 => 0x5)实际上,不是枚举所有可执行页面,而是user32.dll在这种情况下找到函数所在的模块(),并且仅在该模块内搜索.