2015年1月23日 星期五

CRC轉ICS(四)

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


CRC轉ICS(四)

話說看到"在次嚴重警告"的公告還蠻無言的
雖然這種事也不是沒看過沒發生過
還是讓人心寒
如果沒有這種小白,
我是很樂意把會的全部分享出來
不過技術是無價的
學得到就是你的
學不起來偷也沒用
比起抓魚給你
不如把你教會如何釣魚
是吧!
其實是希望多栽培黑客
現在小孩潛力無限:)
提外話了
--------------------------------------------------
150.2
這篇來說說怎麼往上層找


這CRC單純只用(一)~(四)的方法還不能轉成ICS,不過是個不錯的教材XD
[ENABLE]
0048B66D:
DB 33 C0 90 90
[DISABLE]
0048B66D:
DB 8B 44 24 04

組語看多了
有時只看到aob也大概知道在幹麻
33 C0 90 90

xor eax,eax
nop
nop
啊!這不是重點,繼續下去
--------------------------------------------------
來到memory view的0048B66D
一如既往,往上拉要開始找call ptr或call
 

What the F***
0048B66D已經是頭了!!
還好叔叔有練過,只shock了0.1秒就想到方法
如果有想到搜尋"call 0048B66D"、"j* 0048B66D"
也不錯,表示你已經對程式的運作方式有感覺了
但通常直接這樣找要一個一個過慮起來很麻煩
運氣好只有幾十個,運氣不好幾百幾千個

大家還記得吧?用call呼叫時,會先把返回地址push到stack中
就先假設這裡也是用某處用call呼叫0048B66D
一定會先push返回值
如果是用jmp類或其他方法的到這就悲劇了,會比較難
所以當執行到這行時
0048B66D - 8B 44 24 04           - mov eax,[esp+04]

你的[esp]就是這副程式結束時要返回的地方,即你要找的上層地址
--------------------------------------------------
這次先說說人工的做法
雖然CE功能強大,但我比較沒在用CE內建的功能
大多都是自己hook
先copy一下會用到的片段
===================
0048B66D - 8B 44 24 04           - mov eax,[esp+04]
0048B671 - 56                    - push esi
0048B672 - 8B F1                 - mov esi,ecx
===================

[ENABLE]
registersymbol(RetAddr)
Alloc(RetAddr,4)
Alloc(MyHook,64)

0048B66D:
jmp MyHook

MyHook:
//push [RetAddr],[esp]    //這樣的想法是沒錯,但語法不對,註1

push eax //我習慣選eax當中間人,先保存原eax值到stack中
mov eax,[esp+04] //註2
mov [RetAddr],eax
pop eax //有push也要記得pop回來,不然crash機會很大

//遠程jmp消耗5個byte,會蓋到的都補回來,再跳回原程式
mov eax,[esp+04]
push esi
jmp 0048B672

[DISABLE]
0048B66D:
mov eax,[esp+04]
push esi

unregistersymbol(RetAddr)
DeAlloc(RetAddr)
DeAlloc(MyHook)

/*
註1:
偷翻一下書(汗)
reg:8、16、32位元通用暫存器其中一個
(AH,AL,BH,BL,CH,DH,CL,AX,BX,CX,DX,SI,DI,BP,SP,EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP)
mem:使用任何標準的記憶體定址模式的一個記體運算元
imm:立即運算元(16進位數字)
segreg:一個16位元的區段暫存器(CS,DS,ES,SS,FS,GS)

mov使用的格式
mov reg,reg
mov mem,reg
mov reg,mem
mov reg16,segreg
mov segreg,reg16
mov reg,imm
mov mem,imm
mov mem16,segreg
mov segreg,mem16
*/

/*
註2:
因為自己多push一個eax所以要多4的偏移量
如果還有其他會影響到stack位置的
也要視情況增減偏移量
*/

--------------------------------------------------

這樣簡單的hook就完成了,再來只要到RetAddr去看上層地址在哪
就能再繼續用(一)~(四)的技巧找下去

不過有時呼叫的也不止一個地方
[RetAddr]可能會一直變動,這只好一一過慮
假設我們不知物理無敵這東西

在網上看的,查資料還不錯
Windows API 首頁
http://tlcheng.twbbs.org/TLCheng/WinAPI/winapi.asp
像是如果要找物理無敵
較單純直接的方法先找winapi

一開始會找跟方格有關 (人、怪、npc等等許多都是用矩形(Rectangle)來計算)
又看似跟怪碰撞有關的
IsRectEmpty、IntersectRect

如果先從IsRectEmpty開始
那麼物理無敵是從哪呼叫IsRectEmpty?
用上述方法可能會得到很多Return Address
因為遊戲中Rect無所不在

要如何過慮,就要把上面的script改寫一下
寫法很多種,看各人習慣XD

假設已經得到一個Return Address但發現不是
或是可能不止要改一個地方時
還是先把那個地址記下
得到mem1、mem2、mem3…
過慮時可能會得到一堆地址

不一定對目前想改的沒用就是那個地址沒用處
也許是在意想不到的地方會發揮作用,可以先留下來
不過這大概是要研發新數據時才需要這麼做

[ENABLE]
registersymbol(RetAddr)
Alloc(RetAddr,4)
Alloc(MyHook,64)
Label(no)

0048B66D:
jmp MyHook

MyHook:

push eax
mov eax,[esp+04]

//一一比較eax,如果是在不要的名單中
//就跳過mov [RetAddr],eax,直接到pop eax
cmp eax,mem1
je no
cmp eax,mem2
je no
cmp eax,mem3
je no



mov [RetAddr],eax

no:
pop eax

mov eax,[esp+04]
push esi
jmp 0048B672

[DISABLE]
0048B66D:
mov eax,[esp+04]
push esi

unregistersymbol(RetAddr)
DeAlloc(RetAddr)
DeAlloc(MyHook)

沒有留言:

張貼留言