我是逆向工程的新手,我想了解更多,我试图反汇编一个目标exe,我遇到了一些我无法解释的函数。希望有人帮忙可以伸出援助之手。
00161000 /$ 83EC 08 SUB ESP,8
00161003 |. 6A 00 PUSH 0 ; /pHandle = NULL
00161005 |. 68 A8311600 PUSH Launcher.001631A8 ; |FileName =
0016100A |. E8 81160000 CALL <JMP.&VERSION.GetFileVersionInfoSiz>; \GetFileVersionInfoSizeW
0016100F |. 890424 MOV DWORD PTR SS:[ESP],EAX
00161012 |. 85C0 TEST EAX,EAX
00161014 |. 0F84 97000000 JE Launcher.001610B1
0016101A |. 56 PUSH ESI
0016101B |. 57 PUSH EDI
0016101C |. 8B3D 8C301600 MOV EDI,DWORD PTR DS:[<&KERNEL32.GetProc>; kernel32.GetProcessHeap
00161022 |. 50 PUSH EAX ; /HeapSize
00161023 |. 6A 08 PUSH 8 ; |Flags = HEAP_ZERO_MEMORY
00161025 |. FFD7 CALL EDI ; |[GetProcessHeap
00161027 |. 50 PUSH EAX ; |hHeap
00161028 |. FF15 98301600 CALL DWORD PTR DS:[<&KERNEL32.HeapAlloc>>; \HeapAlloc
0016102E |. 8BF0 MOV ESI,EAX
00161030 |. 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
00161034 |. 56 PUSH ESI ; /Buffer
00161035 |. 50 PUSH EAX ; |BufSize
00161036 |. 6A 00 PUSH 0 ; |Reserved = 0
00161038 |. 68 A8311600 PUSH Launcher.001631A8 ; |FileName =
0016103D |. E8 42160000 CALL <JMP.&VERSION.GetFileVersionInfoW> ; \GetFileVersionInfoW
00161042 |. 8D4C24 08 LEA ECX,DWORD PTR SS:[ESP+8]
00161046 |. 51 PUSH ECX ; /pValueSize
00161047 |. 8D5424 10 LEA EDX,DWORD PTR SS:[ESP+10] ; |
0016104B |. 52 PUSH EDX ; |ppValue
0016104C |. 68 D0311600 PUSH Launcher.001631D0 ; |pSubBlock = "\"
00161051 |. 56 PUSH ESI ; |pBlock
00161052 |. E8 33160000 CALL <JMP.&VERSION.VerQueryValueW> ; \VerQueryValueW
00161057 |. 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C]
0016105B |. 8B41 08 MOV EAX,DWORD PTR DS:[ECX+8]
0016105E |. 25 0000FFFF AND EAX,FFFF0000
00161063 |. C1E0 0C SHL EAX,0C
00161066 |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
0016106A |. 8B51 08 MOV EDX,DWORD PTR DS:[ECX+8]
0016106D |. 83E2 0F AND EDX,0F
00161070 |. C1E2 18 SHL EDX,18
00161073 |. 0BC2 OR EAX,EDX
00161075 |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
00161079 |. 8B51 0C MOV EDX,DWORD PTR DS:[ECX+C]
0016107C |. 81E2 00007F00 AND EDX,7F0000*
00161082 |. 03D2 ADD EDX,EDX
00161084 |. 0BC2 OR EAX,EDX
00161086 |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
0016108A |. 8B49 0C MOV ECX,DWORD PTR DS:[ECX+C]
0016108D |. 81E1 FF1F0000 AND ECX,1FFF
00161093 |. 81C9 00A00100 OR ECX,1A000
00161099 |. 56 PUSH ESI ; /pMemory
0016109A |. 0BC1 OR EAX,ECX ; |
0016109C |. 6A 00 PUSH 0 ; |Flags = 0
0016109E |. 894424 10 MOV DWORD PTR SS:[ESP+10],EAX ; |
001610A2 |. FFD7 CALL EDI ; |[GetProcessHeap
001610A4 |. 50 PUSH EAX ; |hHeap
001610A5 |. FF15 90301600 CALL DWORD PTR DS:[<&KERNEL32.HeapFree>] ; \HeapFree
001610AB |. 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
001610AF |. 5F POP EDI
001610B0 |. 5E POP ESI
001610B1 |> 83C4 08 ADD ESP,8
001610B4 \. C3 RETN
从地址 00161057 到 00161093 的部分是我真的不明白的事情。其余的只是调用不同的API,所以没有它。(文件名被删除)
如果有人能向我解释这个粗体部分,我真的很感激。
答案 0 :(得分:8)
我的分析看起来像这样。
00161057 |. 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C] ; ppValue = struct VS_FIXEDFILEINFO* 0016105B |. 8B41 08 MOV EAX,DWORD PTR DS:[ECX+8] ; ppValue+8 = dwFileVersionMS 0016105E |. 25 0000FFFF AND EAX,FFFF0000 ; 00161063 |. C1E0 0C SHL EAX,0C ; (dwFileVersionMS & 0xFFFF0000) << 0xC 00161066 |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX ; save that value on stack 0016106A |. 8B51 08 MOV EDX,DWORD PTR DS:[ECX+8] ; ppValue+8 = dwFileVersionMS 0016106D |. 83E2 0F AND EDX,0F 00161070 |. C1E2 18 SHL EDX,18 ; (dwFileVersionMS & 0xF) << 0x18 00161073 |. 0BC2 OR EAX,EDX ; combine with previous value 00161075 |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX ; save that value on stack 00161079 |. 8B51 0C MOV EDX,DWORD PTR DS:[ECX+C] ; ppValue+0xC = dwFileVersionLS 0016107C |. 81E2 00007F00 AND EDX,7F0000* 00161082 |. 03D2 ADD EDX,EDX ; 2*(dwFileVersionLS & 0x7F0000) 00161084 |. 0BC2 OR EAX,EDX ; combine with previous value 00161086 |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX ; save that value on the stack 0016108A |. 8B49 0C MOV ECX,DWORD PTR DS:[ECX+C] ; dwFileVersionLS 0016108D |. 81E1 FF1F0000 AND ECX,1FFF 00161093 |. 81C9 00A00100 OR ECX,1A000 ; dwFileVersionLS & 0x1FFFF | 0x1A000 00161099 |. 56 PUSH ESI ; /pMemory 0016109A |. 0BC1 OR EAX,ECX ; | combine with previous value 0016109C |. 6A 00 PUSH 0 ; |Flags = 0 0016109E |. 894424 10 MOV DWORD PTR SS:[ESP+10],EAX ; | save value on the stack 001610A2 |. FFD7 CALL EDI ; |[GetProcessHeap 001610A4 |. 50 PUSH EAX ; |hHeap 001610A5 |. FF15 90301600 CALL DWORD PTR DS:[] ; \HeapFree 001610AB |. 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8] ; retrieve calculated value for return 001610AF |. 5F POP EDI 001610B0 |. 5E POP ESI 001610B1 |> 83C4 08 ADD ESP,8 001610B4 \. C3 RETN
在C中看起来像:
DWORD ret = ((dwFileVersionMS & 0xFFFF0000) << 0xC) | ((dwFileVersionMS & 0xF) << 0x18) | (2*(dwFileVersionLS & 0x7F0000)) | (dwFileVersionLS & 0x1FFF) | 0x1A000;
答案 1 :(得分:-1)
我认为地址00161057上的指令是一个带有3个参数的函数,当ESP用作参数时,它通常是4个字节(DWORD)。现在,十进制的C是12.现在,内容ESP + C(c作为偏移量)引用第三个参数并存储在ECX中,然后将ECX + 8的内容复制到EAX并认为EAX + 8是一个全局变量。 无论如何,如果我犯了错误,我的意见仍然会得到其他人的改善。
但是,您可以阅读wikibook的 x86反汇编 MOV EAX,DWORD PTR DS的寻址模式:[ECX + 8]指令