嵌入ASM數據需要使用內聯彙編(inline assembly),在Visual C++最基本的樣子如下:
void __declspec(naked) __stdcall 數據名稱()
{
__asm
{
// 數據
}
}
狀況一
我們拿
v159.2 ICS 超級定怪來示範,數據如下://Author: Onion
[Enable]
Alloc(HookEsp, 128)
HookEsp:
Cmp [Esp], 00B32FAC
Jne 00B32FCB
Mov [Esp], 00B32FC3
Jmp 00B32FCB
00FCA738:
DD HookEsp
[Disable]
00FCA738:
DD 00B32FCB
DeAlloc(HookEsp)
我們要將數據改寫並且在
FormMain.h新增一個CheckBox,比照上一篇的作法,然後加入程式碼到FormMain.cpp:DWORD FreezeMobsAddress = 0x00FCA738;
DWORD FreezeMobs_Disable = 0x00B32FCB;
void __declspec(naked) __stdcall FreezeMobs()
{
__asm
{
Cmp dword ptr[Esp], 0x00B32FAC
Jne FreezeMobsBack
Mov dword ptr[Esp], 0x00B32FC3
FreezeMobsBack:
Jmp FreezeMobs_Disable
}
}
DWORD FreezeMobs_Enable = (DWORD)FreezeMobs;
void FormMain::checkBox2_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
if (this->checkBox2->Checked)
{
memcpy((void *)FreezeMobsAddress, &FreezeMobs_Enable, sizeof(FreezeMobs_Enable));
}
else
{
memcpy((void *)FreezeMobsAddress, &FreezeMobs_Disable, sizeof(FreezeMobs_Disable));
}
}
請仔細觀察程式碼與數據之間的關聯,並試著加入其他功能測試。
注意
注意
dword ptr與0x狀況二
以
v159.2 ICS 全職全圖打示範,數據如下:[Enable]
Registersymbol(SuperMapOnOff)
Alloc(SuperMapOnOff, 4)
Alloc(CheckESP, 256)
Label(FullMapAttack)
SuperMapOnOff:
DD 01
CheckESP:
Cmp [SuperMapOnOff], 0
Je 0056D88A
Cmp [Esp+124], 006A3489
Jne 0056D89C
Mov [Esp+124], FullMapAttack
Jmp 0056D89C
FullMapAttack:
lea edi, [esi+00000728]
push edi
lea ecx, [esi+00000740]
add Esp, 04
push esi
mov esi, ecx
mov eax, [011C7274]
mov eax, [eax+94C8]
push eax
lea ecx, [esi+0c]
call 0042C3F9
mov eax, [011C7274]
mov eax, [eax+94CC]
push eax
mov ecx, esi
call 0042C3F9
mov eax, esi
pop esi
Jmp 006A349B
00F282C8:
DD CheckESP
[Disable]
00F282C8:
DD 0056D89C
DeAlloc(CheckESP)
程式碼如下:
DWORD FullMapAttack_OnOff = 0;
DWORD FullMapAttack_Address = 0x00F282C8;
DWORD FullMapAttack_Disable = 0x0056D89C;
DWORD FullMapAttack_Call = 0x0042C3F9;
DWORD FullMapAttack_Jmp = 0x006A349B;
void __declspec(naked) FullMapAttack_Main()
{
__asm
{
lea edi,[esi+0x00000728]
push edi
lea ecx,[esi+0x00000740]
add Esp, 0x04
push esi
mov esi,ecx
mov eax,[0x011C7274]
mov eax,[eax+0x94C8]
push eax
lea ecx,[esi+0x0c]
call FullMapAttack_Call
mov eax,[0x011C7274]
mov eax,[eax+0x94CC]
push eax
mov ecx,esi
call FullMapAttack_Call
mov eax,esi
pop esi
Jmp FullMapAttack_Jmp
}
}
DWORD FullMapAttack_Main_Address = (DWORD)FullMapAttack_Main;
void __declspec(naked) FullMapAttack()
{
__asm
{
Cmp dword ptr[FullMapAttack_OnOff], 0
Je FullMapAttackBack
Cmp dword ptr[Esp+0x124], 0x006A3489
Jne FullMapAttackBack
Push FullMapAttack_Main_Address
Pop dword ptr[Esp+0x124]
FullMapAttackBack:
Jmp FullMapAttack_Disable
}
}
DWORD FullMapAttack_Enable = (DWORD)FullMapAttack;
由於加上了開關
先把HOOK程式碼移出來放到一個獨立的函數(function):
FullMapAttack_OnOff,我們可以改用更方便的寫法來寫開關。先把HOOK程式碼移出來放到一個獨立的函數(function):
void InjectScript()
{
memcpy((void *)FullMapAttack_Address, &FullMapAttack_Enable, sizeof(FullMapAttack_Enable));
}
接著開關處可以直接這樣改:
void FormMain::checkBox3_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
if (this->checkBox3->Checked)
{
// memcpy((void *)FullMapAttack_Address, &FullMapAttack_Enable, sizeof(FullMapAttack_Enable));
FullMapAttack_OnOff = 1;
}
else
{
// memcpy((void *)FullMapAttack_Address, &FullMapAttack_Disable, sizeof(FullMapAttack_Disable));
FullMapAttack_OnOff = 0;
}
}
但要記得在
在第三行先宣告(declare)函數原型(prototype),往後的程式碼才能呼叫
Main()中呼叫(call)InjectScript()才會寫入數據。在第三行先宣告(declare)函數原型(prototype),往後的程式碼才能呼叫
InjectScript()而不會產生編譯錯誤(compilation error)。void InjectScript();
/* 略 */
void Main(void)
{
InjectScript();
/* 略 */
}

進階:在寫入開關值時,也能直接將
dynamic_cast<CheckBox ^>(sender)->Checked賦值(assign)給變數(variable),程式碼將更為簡潔。
沒有留言:
張貼留言