Обратный инженер сборки

Я новичок в реверс-инжиниринге и хочу узнать больше. Я попытался разобрать целевой 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, так что ничего особенного. (Имя файла удалено)

Я очень признателен, если кто-то может объяснить мне выделенную жирным шрифтом часть.


person ReverseEngineer    schedule 08.03.2012    source источник


Ответы (2)


Мой анализ выглядит так.

 
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;
person jcopenha    schedule 09.03.2012
comment
Я нахожу сдвиги более читаемыми в десятичном виде (в C/C++), но все же +1;) - person 0xC0000022L; 10.03.2012
comment
Спасибо за объяснение! Это должно решить мои проблемы! - person ReverseEngineer; 11.03.2012

Я думаю, что инструкция по адресу 00161057 — это функция с 3 параметрами, потому что, когда в качестве параметра используется ESP, обычно это 4 байта (DWORD). Теперь C в десятичном виде равно 12. Теперь содержимое ESP+C (c как смещение) относится к третьему параметру и сохраняется в ECX, затем содержимое ECX+8 копируется в EAX и считается, что EAX+8 является глобальная переменная. В любом случае, мое мнение может быть улучшено кем-то другим, если я ошибаюсь.

Однако вы можете прочитать разборку x86 в викибуке и режим адресации для инструкции MOV EAX,DWORD PTR DS:[ECX+8]

person user2770352    schedule 17.07.2014