2015年1月23日 星期五

CRC轉ICS(三)

作者:kkmomo
來源:
備註:如果作者不希望被轉帖到此處,請告知,小弟會馬上刪帖。
-------------------------------------------------------------------------------------


CRC轉ICS(三)

v150.2
狀況三:在同一層往上找不到call ptr
這時要用一些別的方法
往下層找或往上層找
這篇先講往下層找

從想改的地方往上
只要看到call即使不是call ptr也進去看一下
call ptr太遠,想縮簡代碼時也可用這方法試找看看



有時ICS會看到像
cmp [esp+10],004EC3AC
cmp [esp+offset],addr

大多數都是[esp],至於後面的+offset怎麼來的
先簡單說明一下esp是在幹麻的
esp : extended stack pointer
為32位元堆疊指位器
esp永遠指著堆疊的頂端
32位元中每push一個,esp值就會-4
反之,每pop一個,esp值就會+4
呼叫call指令時,會將call的下一行位址push到堆疊中
以ret離開副程式後會自動pop掉
===================
舉個簡單的例子
在00401000呼叫讓eax=0的副程式
----堆疊區狀態----
00281000 00000003
00280FFC 00000456
00280FF8 00000789  ←esp
00280FF4 00000442
----堆疊區狀態----
----程式區----
00401000 call 10000000
00401005 test eax,eax

10000000 xor eax,eax
10000002 ret
----程式區----
===================
call 10000000

EIP=00401000
esp=00280FF8
[esp]=789

00281000 00000003
00280FFC 00000456
00280FF8 00000789 ←esp
00280FF4 00000442
===================
xor eax,eax

EIP:10000000
esp=00280FF4
[esp]=00401005

00281000 00000003
00280FFC 00000456
00280FF8 00000789
00280FF4 00401005 ←esp
===================
ret

EIP:10000002
esp=00280FF4
[esp]=00401005

00281000 00000003
00280FFC 00000456
00280FF8 00000789
00280FF4 00401005 ←esp
===================
test eax,eax

EIP:00401005
esp=00280FF8
[esp]=00000789

00281000 00000003
00280FFC 00000456
00280FF8 00000789 ←esp
00280FF4 00401005
===================

詳細說明看書比較快XD
google一下應該也很多教學網站寫得比我清楚
這方面我就不再多廢話了,請看範例
--------------------------------------------------------
這次以物品定位為例,一時想不到有什麼比較短的實例,又懶得自己亂掰XD
CRC
[enable]
004EC443:
DB 90 90
[disable]
004EC443:
DB 75 4F
--------------------------------------------------------
從004EC443往上看,可以看到好幾個call
但我只找圈起來的那幾個
原因為在虛線中的區段可能會因je、jne的關係不一定會執行到
要怎麼先簡單過慮,就要看je、jne、jmp等會改變流程的指令

首先由下往上找call,採用深度優先搜尋法 - DFS(Depth-First-Search)
即一看到call就先進到下一層去,進去後是往下找,直到碰到ret反回上一層,再往上找下一個call
如果call裡面還有call就再跟進下一層,如此反覆找到call ptr為止
(level 0)


第1個(level 1)
004EC3DC - E8 B4F3FFFF           - call 004EB795
裡面雖然還有一個call但在不一定會執行到,先不考慮,反回上層繼續


第2個(level 1)
004EC3D2 - E8 EEEDFFFF           - call 004EB1C5
也沒發現,再下一個


第3個(level 1)
004EC3B8 - E8 559F4600           - call 00956312
也沒有,再下一個


第4個(level 1)
004EC3A7 - E8 B0F2FFFF           - call 004EB65C
雖然沒有call ptr,但有沒在虛線中的call
從第一個call 004EB62E開始


第4-1個(level 2)
004EB65F - E8 CAFFFFFF           - call 004EB62E
終於發現了,感動T_T


找到call ptr後,eax+04用上一篇的法方找就可以

但改ICS的方法略有不同

004EB639 - FF 50 04              - call dword ptr [eax+04]
004EB63C - 84 C0                 - test al,al

原本找到call ptr後我們的返回值會是他的下一行004EB63C
但這裡不是我們原本的那層,而是進了兩層call之後的
我們要的返回值是要在level 0的,而offset要多少才會是我們要的呢

這就要先回到level 0來看
把相關的代碼複製過來
實際上只要看會影響到stack變化的esp、ebp、push、pushf、pushad、pop、popf、popad、leave(不知有沒有漏寫XD)
通常只有push跟pop比較會遇到

我們要的返回值是004EC3AC
假設[eax+04]=12345678

ICS最後的形式應該是會寫成
CheckEsp:
cmp [esp+offset],004EC3AC
jne 12345678
mov [esp+offset],MyFunction
jmp 12345678
-----------------------------------------------------------
level 0
004EC3A7 - E8 B0F2FFFF           - call 004EB65C
004EC3AC - 85 C0                 - test eax,eax

level 1
004EB65C - 56                    - push esi
004EB65D - 8B F1                 - mov esi,ecx
004EB65F - E8 CAFFFFFF           - call 004EB62E
004EB664 - 85 C0                 - test eax,eax

level 2
004EB62E - 56                    - push esi
004EB62F - 8B B1 B81F0000        - mov esi,[ecx+00001FB8]
004EB635 - 8B 06                 - mov eax,[esi]
004EB637 - 8B CE                 - mov ecx,esi
004EB639 - FF 50 04              - call dword ptr [eax+04]
004EB63C - 84 C0                 - test al,al

怎麼算出offset是多少,簡單意示一下
當進到 call dword ptr [eax+04]之後stack的狀態

004EC3AC      (by 004EC3A7)←esp+10
esi                 (by 004EB65C)←esp+0C
004EB664      (by 004EB65F)←esp+08
esi                 (by 004EB62E)←esp+04
004EB63C      (by 004EB639)←esp

每一個差是4 byte
所以可以算得offset=10
關鍵的幾個都有了
剩下的就跟前面做法一樣了
you can do it! !

沒有留言:

張貼留言