背景是要用c++ / asm 修改記憶體實作hook 的功能
一般遇到記憶體中代碼
mov eax , 0xabcdef (1)
call addr
類似這樣的 可以找個5位元組的指令改成JMP myfunc 跳到自己函式的地址,然后讀取相關資料再jmp回來。
問題是jmp代碼+記憶體有3個位元組的 5個位元組 6位元組的都有, mov一般都是5位元組
改成跳自己函式還好,但是恢復現場能不能自動的來生成呢?
比如自己的函式是
VOID __declspec(naked) myfunc()
{
PUSH_DATA; ///備份各暫存器的值
ProcessData( (void*)dwESI); // 用esi的內容,自己處理相關資料
RESTORE_DATA; //恢復暫存器內容
__asm {
mov eax, 0xabcdef; // (2)
jmp dword ptr [lpBackAddr]; // (3)
}
}
為了解決call jmp長度《5的問題,可以在前面找個5的指令,改一下,跳myfunc 然后再myfunc最后(3)的地方跳回來就行
當然要在(3)之前把(1)的內容寫在(2)這里。 對于簡單的一個呼叫直接反匯編并把指令寫上就行了。
如果有若干個這樣的函式和地址要截獲想做到自動一點的話,應該是:
另外字義一個函式sethook
a. (2)處先預留5位元組
b. 把(1)處5位元組的資料存起來, ReadProcessMemory或者直接記憶體訪問
c. 找到2的偏移,把對應的記憶體用b得到的內容寫進去。
d. 或者在(2)的地方設定 cs:ip 到 b讀取出來內容(這應該是資料段,能設定執行么?) 在讀取出來的內容后面加個跳轉指令,即把(3)也放在上面,這樣執行完后就自動跳回去了。
問題:
1. c++怎么能獲取(2)的偏移呢?好像沒有類似offset計算記憶體偏移一樣,可以自動計算某行代碼編譯后相對函式起始地址的偏移。
2. (2)的地方內容是動態的 是不是可以?怎么實作 ?也就是說怎么在一個函式里去修改另一個函式指定的內容,或者在這個函式里怎么自己動態調整代碼內容
3. 是不是可以搞個類似下面的函式 在myfunc里跳myfunc2 在初始化的時候可以把指令搞到這里?這樣myfunc2的地址是知道的,就不需要知道具體某行代碼的地址了
VOID __declspec(naked) myfunc2()
{
__asm {
NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
}
}
說得有點亂,希望有人能看明白指點一下。多謝。
uj5u.com熱心網友回復:
1. ms的編譯器不能用這個功能,gcc可以。2.3. 你這個想法就是鉤子
uj5u.com熱心網友回復:
https://github.com/Jasey/hookuj5u.com熱心網友回復:
WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/uj5u.com熱心網友回復:
是鉤子啊。只不過想找一段記憶體自動的把需要修改的一處指令自動復制過去,然后運行完自己的功能能自動恢復。
不知道怎么搞。
把主程式里的一些指令,放到另一個dll里會不會有問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/42119.html
標籤:進程/線程/DLL
