Hying 脫殼 IAT 亂序修復
【目 標】:天翼天使內掛 1021
【工 具】:OllyICE、ImportREC1.6F、WinHEX
【任 務】:Crack
【平 臺】:Windows XP SP3
一 找尋 OEP
先找 IAT 的位址
OD 載入,先 F9 RUN 一次,看到數據視窗...
00432000 77DA6C17 advapi32.RegCloseKey
00432004 77DCBB5D advapi32.RegQueryValueA
00432008 77DA7842 advapi32.RegOpenKeyExA
0043200C 77DAE9E4 advapi32.RegCreateKeyExA
00432010 77DAEAD7 advapi32.RegSetValueExA
00432000 就是 IAT 開始的地方。
重新載入,在 IAT 00432000 下記憶體寫入中斷點,F9 RUN 斷在 00393775 然後刪除記憶體斷點。
00393775 F3:A4 rep movs byte ptr es:[edi], byte ptr [esi] ; 停在這裡
00393777 5E pop esi
00393778 53 push ebx
00393779 68 00800000 push 8000
0039377E 6A 00 push 0
00393780 56 push esi
00393781 8D85 EF1A4000 lea eax, dword ptr [ebp+401AEF]
00393787 50 push eax
00393788 8B85 33314000 mov eax, dword ptr [ebp+403133]
0039378E E9 E8090000 jmp 0039417B
然後搜尋 HEX:8B 7C 24 24 8B 74 24 28 66 8B 06 3C 50
也就是在 IAT 加密處理代碼(00394190)上面的 retn(0039417A),就是要返回 OEP 的地方。
0039412B B9 76170000 mov ecx, 1776
00394130 C1E9 02 shr ecx, 2
00394133 EB 08 jmp short 0039413D
00394135 AD lods dword ptr [esi]
00394136 3185 7E304000 xor dword ptr [ebp+40307E], eax
0039413C 49 dec ecx
0039413D 0BC9 or ecx, ecx
0039413F ^ 75 F4 jnz short 00394135
00394141 8B9D 76304000 mov ebx, dword ptr [ebp+403076]
00394147 83FB 01 cmp ebx, 1
0039414A 75 0E jnz short 0039415A
0039414C 61 popad
0039414D 8B4424 CC mov eax, dword ptr [esp-34] ; 堆疊 ss:[0012FF90]=00415CD5 (lordtyy.00415CD5)
00394151 8D78 02 lea edi, dword ptr [eax+2] ; 位址=00415CD7
00394154 55 push ebp
00394155 8BEC mov ebp, esp
00394157 50 push eax ; eax=00415CD5 (lordtyy.00415CD5)
00394158 EB 20 jmp short 0039417A
0039415A 83FB 02 cmp ebx, 2
0039415D 75 15 jnz short 00394174
0039415F 61 popad
00394160 8B4424 C8 mov eax, dword ptr [esp-38]
00394164 FFB0 7A304000 push dword ptr [eax+40307A]
0039416A 8B4424 D0 mov eax, dword ptr [esp-30]
0039416E 50 push eax
0039416F 8D78 02 lea edi, dword ptr [eax+2]
00394172 EB 06 jmp short 0039417A
00394174 61 popad
00394175 8B4424 CC mov eax, dword ptr [esp-34]
00394179 50 push eax
0039417A C3 retn ; 返回 OEP
0039417B 50 push eax
0039417C 8B85 92344000 mov eax, dword ptr [ebp+403492]
00394182 50 push eax
00394183 E8 08000000 call 00394190
00394188 8B85 92344000 mov eax, dword ptr [ebp+403492]
0039418E FFE0 jmp eax
00394190 60 pushad ; IAT 指標加密處理
00394191 8B7C24 24 mov edi, dword ptr [esp+24]
00394195 8B7424 28 mov esi, dword ptr [esp+28]
00394199 66:8B06 mov ax, word ptr [esi]
0039419C 3C 50 cmp al, 50
0039419E 72 0A jb short 003941AA ; 改為 JMP 003942EC
003941A0 3C 57 cmp al, 57
003941A2 77 06 ja short 003941AA
0039417A retn 下斷,然後 F9 -> F8 返回到 OEP(00415CD5)。
00415CD5 . FFD7 call edi ; OEP 入口點
00415CD7 . 58 pop eax
00415CD8 . 6A FF push -1
00415CDA . 68 80884300 push 00438880
00415CDF . 68 F0A04100 push 0041A0F0
00415CE4 . 64:A1 0000000>mov eax, dword ptr fs:[0]
00415CEA . 50 push eax
00415CEB . 64:8925 00000>mov dword ptr fs:[0], esp
00415CF2 . 83EC 58 sub esp, 58
00415CF5 . 53 push ebx
00415CF6 . 56 push esi
00415CF7 . 57 push edi
00415CF8 . 8965 E8 mov dword ptr [ebp-18], esp
00415CFB . 90 nop
00415CFC . E8 04E6F7FF call 00394305 ; 亂序 Call
OEP 入口有三個 Byte 被修改,補上 HEX:55 8B EC 改回來。
00415CD5 >/$ 55 push ebp
00415CD6 |. 8BEC mov ebp, esp
00415CD8 |. 6A FF push -1
00415CDA |. 68 80884300 push 00438880
00415CDF |. 68 F0A04100 push 0041A0F0 ; SE 處理程序安裝
00415CE4 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
00415CEA |. 50 push eax
00415CEB |. 64:8925 00000>mov dword ptr fs:[0], esp
00415CF2 |. 83EC 58 sub esp, 58
00415CF5 |. 53 push ebx
00415CF6 |. 56 push esi
00415CF7 |. 57 push edi
OEP = 00415CD5
亂序 Call = 00394305
二 IAT 修復
// 分析-------------------------------------------
重新載入,在 IAT 00432000 下記憶體寫入中斷點,F9 RUN 斷在 00393775 然後刪除記憶體斷點。
00393775 F3:A4 rep movs byte ptr es:[edi], byte ptr [esi] ; 停在這裡
00393777 5E pop esi
00393778 53 push ebx
00393779 68 00800000 push 8000
0039377E 6A 00 push 0
00393780 56 push esi
00393781 8D85 EF1A4000 lea eax, dword ptr [ebp+401AEF]
00393787 50 push eax
00393788 8B85 33314000 mov eax, dword ptr [ebp+403133]
0039378E E9 E8090000 jmp 0039417B
搜尋 HEX:8B 7C 24 24 8B 74 24 28 66 8B 06 3C 50
找到這段代碼...
IAT加密處理修改
00394190 60 pushad
00394191 8B7C24 24 mov edi, dword ptr [esp+24]
00394195 8B7424 28 mov esi, dword ptr [esp+28]
00394199 66:8B06 mov ax, word ptr [esi]
0039419C 3C 50 cmp al, 50
0039419E 72 0A jb short 003941AA ; 改為 JMP 003942EC
003941A0 3C 57 cmp al, 57
003941A2 77 06 ja short 003941AA
003941A4 8807 mov byte ptr [edi], al
003941A6 46 inc esi
003941A7 47 inc edi
003941A8 ^ EB EF jmp short 00394199
003941AA 3C 6A cmp al, 6A
003941AC 75 09 jnz short 003941B7
.....略......
003942EC C607 68 mov byte ptr [edi], 68 ; 跳到這裡
003942EF 8977 01 mov dword ptr [edi+1], esi
003942F2 C647 05 C3 mov byte ptr [edi+5], 0C3
003942F6 83C7 06 add edi, 6
003942F9 897C24 FC mov dword ptr [esp-4], edi
003942FD 61 popad
003942FE 8B4424 DC mov eax, dword ptr [esp-24]
00394302 C2 0800 retn 8
將 0039419E jb short 003941AA 改為 JMP 003942EC
然後 OEP F2 下斷點 RUN,在數據視窗找到被加密的IAT。
004320D8 77F0C63D gdi32.GetTextExtentPoint32A
004320DC 77EF6F79 gdi32.BitBlt
004320E0 77EF61A5 gdi32.CreateSolidBrush
004320E4 77EF5B70 gdi32.SelectObject
004320E8 77F1D30E gdi32.ScaleViewportExtEx
004320EC 77EFE9AE gdi32.Rectangle
004320F0 77EF7786 gdi32.CreateRectRgn
004320F4 00000000
004320F8 003F0000 被加密的IAT
004320FC 003F0020
00432100 003F0040
00432104 003F0060
00432108 003F0080
0043210C 003F00A0
00432110 003F00C0
.....
0043233C 5E5C1FD7 olepro32.OleCreateFontIndirect
00432340 00000000
00432344 7D611150 shell32.ShellExecuteA
00432348 7D5F21D6 shell32.Shell_NotifyIconA
0043234C 00000000
00432350 00960000
00432354 00960020
00432358 00960040
0043235C 00960060
GoTo 003F0000 新建 EIP,F8 Run 一次。
003F0000 8135 1C003F00 929CC52F xor dword ptr [3F001C], 2FC59C92
003F000A FF35 1C003F00 push dword ptr [3F001C]
003F0010 8135 1C003F00 929CC52F xor dword ptr [3F001C], 2FC59C92
003F001A C3 retn
返回到 003E0000
003E0000 68 E10E817C push kernel32.GetFileType
003E0005 C3 retn
多半 F7/F8 都可以到達目的地。
// 修改-------------------------------------------
分析完成後就,一樣重新載入,在 IAT 下記憶體寫入中斷點 F9 RUN,刪除記憶體斷點 -> IAT加密處理代碼改 JMP -> OEP 下斷 F9 RUN。
然後找空白處打 Patch。
004319C5 60 pushad
004319C6 9C pushfd
004319C7 BA F8204300 mov edx, 004320F8 ; 被加密 IAT 開始的位址,或者 IAT 開始位址。
004319CC 33DB xor ebx, ebx
004319CE 8B32 mov esi, dword ptr [edx]
004319D0 8B7A 04 mov edi, dword ptr [edx+4]
004319D3 3BF7 cmp esi, edi ; IAT 表結束通常有 8Byte 的00,各取4Byte來比較是否結束。
004319D5 74 2A je short 00431A01 ; IAT 結束則跳
004319D7 66:8B5A 02 mov bx, word ptr [edx+2]
004319DB 66:81FB 3F00 cmp bx, 3F ; 加密IAT指標+2 (kernel32 部分)
004319E0 74 07 je short 004319E9
004319E2 66:81FB 9600 cmp bx, 96 ; 加密IAT指標+2 (user32 部分)
004319E7 75 13 jnz short 004319FC
004319E9 8B0A mov ecx, dword ptr [edx]
004319EB 8B79 02 mov edi, dword ptr [ecx+2]
004319EE 8B71 06 mov esi, dword ptr [ecx+6]
004319F1 3137 xor dword ptr [edi], esi
004319F3 8B0F mov ecx, dword ptr [edi]
004319F5 3137 xor dword ptr [edi], esi
004319F7 8B41 01 mov eax, dword ptr [ecx+1]
004319FA 8902 mov dword ptr [edx], eax
004319FC 83C2 04 add edx, 4
004319FF ^ EB CD jmp short 004319CE
00431A01 9D popfd
00431A02 61 popad
00431A03 ^ E9 D042FEFF jmp 00415CD5 ; 返回 OEP
加密IAT指標+2:例如 IAT 加密指標為 003FXXXX,則代碼就寫「cmp bx, 3F」。若 IAT 加密指標為 0078XXXX,則代碼就寫「cmp bx, 78」。
上面一個是偵測 kernel32 加密與 user32 加密部分。
60 9C BA F8 20 43 00 33 DB 8B 32 8B 7A 04 3B F7 74 2A 66 8B 5A 02 66 81 FB 3F 00 74 07 66 81 FB
96 00 75 13 8B 0A 8B 79 02 8B 71 06 31 37 8B 0F 31 37 8B 41 01 89 02 83 C2 04 EB CD 9D 61 E9 D0
42 FE FF
跑完後將修復好的 IAT 記錄起來,若中途碰到無法修復的部分。
例如:
00432220 7C92FE01 ntdll.RtlGetLastWin32Error
00432224 7C81CAFA kernel32.ExitProcess
00432228 7C8623AD kernel32.WinExec
0043222C 003F09A0
00432230 003F09C0
00432234 7C802446 kernel32.Sleep
00432238 7C8309D1 kernel32.OpenProcess
0043223C 7C801E1A kernel32.TerminateProcess
Patch 跑完後直接前往 003F09A0 / 003F09C0 新建 EIP,單步 Run 一次就可以走到目的地。
『0043222C 003F09A0』
直接 Goto 003F09A0 新建 EIP,F7 Run 下去。
003F09A0 8135 BC093F00 39BA764D xor dword ptr [3F09BC], 4D76BA39
003F09AA FF35 BC093F00 push dword ptr [3F09BC]
003F09B0 8135 BC093F00 39BA764D xor dword ptr [3F09BC], 4D76BA39
003F09BA C3 retn
返回到
003946A1 6A 01 push 1
003946A3 E9 06010000 jmp 003947AE
003947AE /EB 01 jmp short 003947B1
003947B1 68 C2100000 push 10C2
003947B6 E8 01000000 call 003947BC
003947BC 68 24080E68 push 680E0824
003947C1 68 90908344 push 44839090
003947C6 FFE4 jmp esp
0012FB78 90 nop
0012FB79 90 nop
0012FB7A 834424 08 0E add dword ptr [esp+8], 0E
0012FB7F 68 BB473900 push 3947BB
0012FB84 C2 1000 retn 10
003947C9 E8 03000000 call 003947D1
003947D1 58 pop eax ; 003947CE
003947D2 EB 01 jmp short 003947D5
003947D5 83C0 07 add eax, 7
003947D8 50 push eax
003947D9 C3 retn
003947D5 83C0 07 add eax, 7
003947D8 50 push eax
003947D9 C3 retn
003947DC 58 pop eax ; 這裡才真正開始
003947DD 83F8 01 cmp eax, 1
003947E0 0F85 D9000000 jnz 003948BF
003947E6 50 push eax
003947E7 60 pushad
003947E8 E8 00000000 call 003947ED
003947ED 5D pop ebp
003947EE 81ED 482B4000 sub ebp, 402B48
003947F4 8B4424 28 mov eax, dword ptr [esp+28]
003947F8 50 push eax
003947F9 8D85 8B324000 lea eax, dword ptr [ebp+40328B]
003947FF 50 push eax
00394800 FF95 5A314000 call dword ptr [ebp+40315A] ; 這裡記得千萬要F7
00394806 0BC0 or eax, eax
00394808 75 0D jnz short 00394817
00394817 8B4424 28 mov eax, dword ptr [esp+28]
0039481B 66:8B08 mov cx, word ptr [eax]
0039481E 66:83F9 01 cmp cx, 1
00394822 75 1E jnz short 00394842
00394842 66:83F9 02 cmp cx, 2
00394846 75 1C jnz short 00394864
00394864 66:83F9 03 cmp cx, 3
00394868 75 1E jnz short 00394888
00394888 66:83F9 04 cmp cx, 4
0039488C 75 1A jnz short 003948A8
003948A8 8B85 4E304000 mov eax, dword ptr [ebp+40304E] ; ss:[00394CF3]=7C801D7B (kernel32.LoadLibraryA)
003948AE 894424 20 mov dword ptr [esp+20], eax ; eax=7C801D7B (kernel32.LoadLibraryA)
003948B2 61 popad
003948B3 83C4 04 add esp, 4
003948B6 - FF6424 FC jmp dword ptr [esp-4] ; 堆疊 ss:[0012FFBC]=7C801D7B (kernel32.LoadLibraryA)
IAT 0043222C 就是 7C801D7B (kernel32.LoadLibraryA) 。
『00432230 003F09C0』
直接 Goto 003F09C0 新建 EIP,F7 Run 下去。
003F09C0 8135 DC093F00 24D4D0FA xor dword ptr [3F09DC], FAD0D424
003F09CA FF35 DC093F00 push dword ptr [3F09DC]
003F09D0 8135 DC093F00 24D4D0FA xor dword ptr [3F09DC], FAD0D424
003F09DA C3 retn
返回到
003946A8 6A 02 push 2
003946AA E9 FF000000 jmp 003947AE
003947AE /EB 01 jmp short 003947B1
003947B1 68 C2100000 push 10C2
003947B6 E8 01000000 call 003947BC
003947BC 68 24080E68 push 680E0824
003947C1 68 90908344 push 44839090
003947C6 FFE4 jmp esp
0012FFAC 90 nop
0012FFAD 90 nop
0012FFAE 834424 08 0E add dword ptr [esp+8], 0E
0012FFB3 68 BB473900 push 3947BB
0012FFB8 C2 1000 retn 10
003947C9 E8 03000000 call 003947D1
003947D1 58 pop eax ; 003947CE
003947D2 EB 01 jmp short 003947D5
003947D5 83C0 07 add eax, 7
003947D8 50 push eax
003947D9 C3 retn
003947D5 83C0 07 add eax, 7
003947D8 50 push eax
003947D9 C3 retn
003947DC 58 pop eax ; 這裡才真正開始
003947DD 83F8 01 cmp eax, 1
003947E0 0F85 D9000000 jnz 003948BF
003948BF 83F8 02 cmp eax, 2
003948C2 0F85 19020000 jnz 00394AE1
003948C8 50 push eax
003948C9 60 pushad
003948CA E8 00000000 call 003948CF
003948CF 5D pop ebp
003948D0 81ED 2A2C4000 sub ebp, 402C2A
003948D6 8B4424 28 mov eax, dword ptr [esp+28]
003948DA 3D 78787878 cmp eax, 78787878
003948DF 0F85 DD000000 jnz 003949C2
003949C2 3D 69696969 cmp eax, 69696969
003949C7 75 0D jnz short 003949D6
003949D6 8B4424 2C mov eax, dword ptr [esp+2C]
003949DA 3D 00000080 cmp eax, 80000000
003949DF 0F83 E5000000 jnb 00394ACA
003949E5 8A08 mov cl, byte ptr [eax]
003949E7 80F9 01 cmp cl, 1
003949EA 75 5F jnz short 00394A4B
00394A4B 80F9 02 cmp cl, 2
00394A4E 75 44 jnz short 00394A94
00394A94 80F9 03 cmp cl, 3
00394A97 75 17 jnz short 00394AB0
00394AB0 80F9 04 cmp cl, 4
00394AB3 75 15 jnz short 00394ACA
00394ACA 8B85 46304000 mov eax, dword ptr [ebp+403046] ; ss:[00394CEB]=7C80AE30 (kernel32.GetProcAddress)
00394AD0 894424 20 mov dword ptr [esp+20], eax ; eax=7C80AE30 (kernel32.GetProcAddress)
00394AD4 61 popad
00394AD5 83C4 04 add esp, 4
00394AD8 - FF6424 FC jmp dword ptr [esp-4] ; 堆疊 ss:[0012FFBC]=7C80AE30 (kernel32.GetProcAddress)
IAT 00432230 就是 7C80AE30 (kernel32.GetProcAddress) 。
三 亂序 Call 修復
// 分析-------------------------------------------
重新載入在 IAT 下記憶體寫入中斷點 F9 RUN,刪除記憶體斷點 -> IAT加密處理代碼改 JMP -> OEP 下斷 F9 RUN。
到 OEP 取消斷點,以 F7 進入「亂序 Call」。
切忌:由 OEP/Code 區段單步進入「亂序 Call」來分析是最安全的,千萬別直接在「亂序 Call」內下斷點直接 F9。
未經由 Code 區段的「亂序 Call」進入跑代碼,時常造成 00394385 eax, dword ptr [ebp+40307E] 指標內的數據錯誤,會造成計算 IAT 指標算錯。
F7 進入後,在 00394346 下記憶體中斷點 F9。
00394305 50 push eax
00394306 60 pushad
00394307 E8 06000000 call 00394312
0039430C 8B6424 08 mov esp, dword ptr [esp+8]
00394310 EB 20 jmp short 00394332
00394312 64:FF35 0000000>push dword ptr fs:[0]
00394319 64:8925 0000000>mov dword ptr fs:[0], esp
00394320 9C pushfd
00394321 810C24 00010000 or dword ptr [esp], 100
00394328 9D popfd
00394329 90 nop
0039432A 64:8F05 0000000>pop dword ptr fs:[0]
00394331 - E9 648F0500 jmp 003ED29A
00394336 0000 add byte ptr [eax], al
00394338 0058 E8 add byte ptr [eax-18], bl
0039433B 0000 add byte ptr [eax], al
0039433D 0000 add byte ptr [eax], al
0039433F 5D pop ebp
00394340 81ED 9A264000 sub ebp, 40269A
00394346 8B7C24 24 mov edi, dword ptr [esp+24] ;「亂序 Call 返回位址」
0039434A 8DB5 F2154000 lea esi, dword ptr [ebp+4015F2]
00394350 03B5 8E304000 add esi, dword ptr [ebp+40308E]
00394356 8B06 mov eax, dword ptr [esi] ; ESI=00396851 為亂序表指標
00394358 33D2 xor edx, edx
0039435A B9 02000000 mov ecx, 2
0039435F F7E1 mul ecx
00394361 D1E8 shr eax, 1
00394363 0385 56304000 add eax, dword ptr [ebp+403056]
00394369 2B85 62304000 sub eax, dword ptr [ebp+403062]
0039436F 3BF8 cmp edi, eax
00394371 75 0A jnz short 0039437D
00394373 0AD2 or dl, dl ; 這裡 F4
00394375 75 04 jnz short 0039437B
00394377 EB 09 jmp short 00394382
00394379 EB 02 jmp short 0039437D
0039437B EB 35 jmp short 003943B2
0039437D 83C6 08 add esi, 8
00394380 ^ EB D4 jmp short 00394356
跟到 00394382 這段代碼
EDI=「亂序 Call 返回位址」
ESI= 對照亂序表內「亂序 Call 返回位址」指標
亂序表是以對照表內「亂序 Call 返回位址」的後面 4 Byte 的數值,來計算存取 IAT 的指標。
00394382 8B46 04 mov eax, dword ptr [esi+4] ;「亂序 Call 返回位址」後面 4 Byte 的數值。
00394385 0385 7E304000 add eax, dword ptr [ebp+40307E] ; ss:[00394D23]=168D060E (紀錄下來)
0039438B 03BD 62304000 add edi, dword ptr [ebp+403062]
00394391 2BBD 56304000 sub edi, dword ptr [ebp+403056]
00394397 2BC7 sub eax, edi ; 計算開始
00394399 F7D0 not eax
0039439B C1C0 10 rol eax, 10
0039439E 0385 56304000 add eax, dword ptr [ebp+403056] ; eax=0043227C IAT 指標
003943A4 2B85 62304000 sub eax, dword ptr [ebp+403062]
003943AA 8B00 mov eax, dword ptr [eax]
003943AC 894424 20 mov dword ptr [esp+20], eax
003943B0 61 popad
003943B1 C3 retn
003943B2 8B46 04 mov eax, dword ptr [esi+4]
003943B5 0385 7E304000 add eax, dword ptr [ebp+40307E]
003943BB 03BD 62304000 add edi, dword ptr [ebp+403062]
003943C1 2BBD 56304000 sub edi, dword ptr [ebp+403056]
003943C7 2BC7 sub eax, edi
003943C9 F7D0 not eax
003943CB C1C0 10 rol eax, 10
003943CE 0385 56304000 add eax, dword ptr [ebp+403056]
003943D4 2B85 62304000 sub eax, dword ptr [ebp+403062]
003943DA 8B00 mov eax, dword ptr [eax]
003943DC 894424 24 mov dword ptr [esp+24], eax
003943E0 61 popad
003943E1 83C4 04 add esp, 4
003943E4 C3 retn
把 00394385 [ebp+40307E] 指標的數據 168D060E 紀錄下來,後面打 Patch 用。
亂序表
00396851 56 11 40 00 04 0B 73 C7 5F 11 40 00 0D 0B A7 C6 V@.s@..希
00396861 C6 11 40 00 74 0B 67 C4 4C 12 40 00 FA 0B 87 C7 ?@.tg鶉@.?
00396871 5D 12 40 00 0B 0C 83 C7 79 12 40 00 27 0C 5F C4 ]@..y@.'._
00396881 84 12 40 00 32 0C 7F C7 8A 12 40 00 38 0C 5B C4 ?@.2.?@.8.[
00396891 A8 12 40 00 56 0C 7B C7 B5 12 40 00 63 0C 77 C7 ?@.V.{@.c.w
亂序表內「亂序 Call 返回位址」為 XX XX 4X 00 ,操作代碼原型為 call dword ptr [XXXXXXXX]。
如果是 XX XX 4X 80 ,那操作代碼的原型為 jmp dword ptr [XXXXXXXX]。
// 修改-------------------------------------------
對照亂序表來對照修改 Code 段的「亂序 Call」。
重新載入在 IAT 下記憶體寫入中斷點 F9 RUN,刪除記憶體斷點 -> IAT 加密處理代碼改 JMP -> OEP 下斷 F9 RUN,取消斷點。
然後找空白處打 Patch 打完後在 Patch 的位置新建 EIP 然後 Run
004319C9 60 pushad
004319CA 9C pushfd
004319CB BE 51683900 mov esi, 396851 ; 亂序表指標
004319D0 33DB xor ebx, ebx
004319D2 8A5E 03 mov bl, byte ptr [esi+3]
004319D5 80FB 00 cmp bl, 0 ; 比較「亂序 Call 返回位址」是否 80 開頭
004319D8 75 2C jnz short 00431A06 ; 是則跳往 FF25 Patch 處理
004319DA 8B3E mov edi, dword ptr [esi] ; 表內「亂序 Call 返回位址」移到 EDI
004319DC 8BD7 mov edx, edi
004319DE 8B46 04 mov eax, dword ptr [esi+4] ; 表內「亂序 Call 返回位址」後面 4 Byte 數值移到 EAX
004319E1 05 0E068D16 add eax, 168D060E ; 先前紀錄的數值 168D060E (計算用)
004319E6 2BC7 sub eax, edi ; 計算開始
004319E8 F7D0 not eax
004319EA C1C0 10 rol eax, 10 ; 計算結束
004319ED 66:C742 FA FF15 mov word ptr [edx-6], 15FF ; EAX 為 IAT 指標 ; 「亂序 Call 返回位址」-6 處改為 Call dword ptr [xxxxxxxx]
004319F3 8942 FC mov dword ptr [edx-4], eax ; 寫入 IAT 指標
004319F6 83C6 08 add esi, 8 ; 繼續亂序下一個表內「亂序 Call」處理
004319F9 8B06 mov eax, dword ptr [esi]
004319FB 85C0 test eax, eax ; 比較表內下一個「亂序 Call 返回位址」是否 = 0 (也就是跑完了)
004319FD ^ 75 D3 jnz short 004319D2 ; 不是則跳
004319FF 9D popfd
00431A00 61 popad
00431A01 ^ E9 D242FEFF jmp 00415CD5 ; 返回 OEP
00431A06 C646 03 00 mov byte ptr [esi+3], 0 ; 將表內「亂序 Call 返回位址」 80 開頭改為 00
00431A0A 8B3E mov edi, dword ptr [esi]
00431A0C 8BD7 mov edx, edi
00431A0E 8B46 04 mov eax, dword ptr [esi+4]
00431A11 05 0E068D16 add eax, 168D060E
00431A16 2BC7 sub eax, edi ; 計算開始
00431A18 F7D0 not eax
00431A1A C1C0 10 rol eax, 10 ; 計算結束
00431A1D 66:C742 FA FF25 mov word ptr [edx-6], 25FF ; EAX 為 IAT 指標 ; 「亂序 Call 返回位址」-6 處改為 Jmp dword ptr [xxxxxxxx]
00431A23 8942 FC mov dword ptr [edx-4], eax ; 寫入 IAT 指標
00431A26 83C6 08 add esi, 8
00431A29 8B06 mov eax, dword ptr [esi]
00431A2B 85C0 test eax, eax
00431A2D ^ 75 A3 jnz short 004319D2
00431A2F 9D popfd
00431A30 61 popad
00431A31 ^ E9 A242FEFF jmp 00415CD5 ; 返回 OEP
60 9C BE 51 68 39 00 33 DB 8A 5E 03 80 FB 00 75 2C 8B 3E 8B D7 8B 46 04 05 0E 06 8D 16 2B C7 F7
D0 C1 C0 10 66 C7 42 FA FF 15 89 42 FC 83 C6 08 8B 06 85 C0 75 D3 9D 61 E9 D2 42 FE FF C6 46 03
00 8B 3E 8B D7 8B 46 04 05 0E 06 8D 16 2B C7 F7 D0 C1 C0 10 66 C7 42 FA FF 25 89 42 FC 83 C6 08
8B 06 85 C0 75 A3 9D 61 E9 A2 42 FE FF
修復完多半 RUN 後有一些小錯誤,就本來是 call dword ptr [XXXXXXXX] 變為 jmp dword ptr [XXXXXXXX]。
搜尋 HEX:FF 25 看看操作代碼,有些根本不是 jmp dword ptr [XXXXXXXX] 該出現的地方,就改為 call dword ptr [XXXXXXXX] 即可。
Hying 好像不能用硬體斷點,下硬體斷點 Run 的話就掛掉了。
[课程]Linux pwn 探索篇!