激情六月丁香婷婷|亚洲色图AV二区|丝袜AV日韩AV|久草视频在线分类|伊人九九精品视频|国产精品一级电影|久草视频在线99|在线看的av网址|伊人99精品无码|午夜无码视频在线

高校合作1:010-59833514 ?咨詢(xún)電話(huà):400-810-1418 服務(wù)與監(jiān)督電話(huà):400-810-1418轉(zhuǎn)接2

游戲開(kāi)發(fā)的c++框架(游戲外掛開(kāi)發(fā)之C/C++內(nèi)聯(lián)匯編代碼和DLL)

發(fā)布時(shí)間:2023-11-27 22:43:34 瀏覽量:122次

?游戲外掛開(kāi)發(fā)之C/C++內(nèi)聯(lián)匯編代碼和DLL

游戲開(kāi)發(fā)的c++框架(游戲外掛開(kāi)發(fā)之C/C++內(nèi)聯(lián)匯編代碼和DLL)

上一節(jié)我講解了CE的使用,這一節(jié)我講解一下windows下C/C++的在以后外掛編程中會(huì)用到的知識(shí),內(nèi)聯(lián)匯編和C++MFC的DLL編寫(xiě)。這兩個(gè)基本知識(shí)都是以后外掛中都會(huì)用到的,但是不一定是現(xiàn)在的高級(jí)語(yǔ)言編寫(xiě)者都會(huì)的知識(shí)。我雖然第一個(gè)語(yǔ)言是C但是我還是以C#發(fā)家的(畢業(yè)后一直主打的還是.NET平臺(tái)的C#開(kāi)發(fā))。

1.C/C++中內(nèi)聯(lián)匯編代碼:新建一個(gè)windows 控制臺(tái)項(xiàng)目代碼如下

#include "stdafx.h"
extern int add(int a,int b);//方法聲明
int main(int argc, _TCHAR* argv[])
{
 int re;
 re=add(1,3);//調(diào)用add方法
 printf("%d",re);
 scanf_s("%d",&re);//純粹為了停頓查看控制臺(tái)輸出的結(jié)果
 return 0;
}
int add(int a,int b){
 _asm{//匯編代碼塊
 mov eax,a
 add eax,b
 mov b,eax
 
 }
 return b;
}

很容易看到在被調(diào)用的add方法中嵌入了匯編代碼。不難看出運(yùn)行結(jié)果為4。以下是圖和真相

通過(guò)這個(gè)簡(jiǎn)單的內(nèi)聯(lián)匯編我相信大家都熟悉了C/C++中嵌入?yún)R編代碼的方式,主要上就是放在_asm{}中。當(dāng)然這其中的代碼和真正的匯編還是有點(diǎn)區(qū)別的。讓我們來(lái)看一下反匯編后的代碼:

extern int add(int a,int b);//方法聲明
int main(int argc, _TCHAR* argv[])
{
00143A30 push ebp 
00143A31 mov ebp,esp 
00143A33 sub esp,0D0h 
00143A39 push ebx 
00143A3A push esi 
00143A3B push edi 
00143A3C lea edi,[ebp-0D0h] 
00143A42 mov ecx,34h 
00143A47 mov eax,0CCCCCCCCh 
00143A4C rep stos dword ptr es:[edi] 
00143A4E mov eax,dword ptr ds:[0014800Ch] 
00143A53 xor eax,ebp 
00143A55 mov dword ptr [ebp-4],eax 
 int re;
 re=add(1,3);//調(diào)用add方法
00143A58 push 3 
00143A5A push 1 
00143A5C call add (01411D6h) 
00143A61 add esp,8 
00143A64 mov dword ptr [re],eax 
 printf("%d",re);
00143A67 mov esi,esp 
00143A69 mov eax,dword ptr [re] 
00143A6C push eax 
00143A6D push 1458A8h 
00143A72 call dword ptr ds:[1492BCh] 
00143A78 add esp,8 
00143A7B cmp esi,esp 
00143A7D call __RTC_CheckEsp (01411E0h) 
 scanf_s("%d",&re);//純粹為了停頓查看控制臺(tái)輸出的結(jié)果
00143A82 mov esi,esp 
00143A84 lea eax,[re] 
00143A87 push eax 
00143A88 push 1458A8h 
00143A8D call dword ptr ds:[1492B8h] 
00143A93 add esp,8 
00143A96 cmp esi,esp 
00143A98 call __RTC_CheckEsp (01411E0h) 
 return 0;
00143A9D xor eax,eax 
}

這是main函數(shù)反匯編過(guò)來(lái)的。下面我們看看add函數(shù)的反匯編代碼:

int add(int a,int b){
001417A0 push ebp 
001417A1 mov ebp,esp 
001417A3 sub esp,0C0h 
001417A9 push ebx 
001417AA push esi 
001417AB push edi 
001417AC lea edi,[ebp-0C0h] 
001417B2 mov ecx,30h 
001417B7 mov eax,0CCCCCCCCh 
001417BC rep stos dword ptr es:[edi] 
 _asm{//匯編代碼塊
 mov eax,a
001417BE mov eax,dword ptr [a] 
 add eax,b
001417C1 add eax,dword ptr [b] 
 mov b,eax
001417C4 mov dword ptr [b],eax 
 
 }
 return b;
001417C7 mov eax,dword ptr [b] 
}

從中可以看出C中內(nèi)聯(lián)匯編和匯編指令還是有點(diǎn)區(qū)別的。在main主函數(shù)中call add這個(gè)就是調(diào)用add函數(shù),再往call add前面看,大家可以看到被調(diào)用的add參數(shù)被從右到左的放到堆棧中去了(匯編基礎(chǔ)知識(shí))。至于add函數(shù)的返回值就放到通用寄存器eax中。匯編中函數(shù)放回值都是放到eax中,add函數(shù)中有這樣一行匯編mov eax,dword ptr [b]。其中 call add后面有add esp,8這個(gè)是為了保持堆棧平衡。這是高級(jí)語(yǔ)言中我們不需要關(guān)注的東西,其它的就不多說(shuō)了。更多的還是自己去掌握匯編吧,畢竟匯編知識(shí)還是比較豐富的,三言?xún)烧Z(yǔ)講不清。這里我只是讓大家能看懂大致的脈絡(luò)。在外掛編程中我們很多時(shí)候是通過(guò)內(nèi)聯(lián)匯編去call游戲線(xiàn)程中的某個(gè)方法,例如我們call補(bǔ)金瘡藥或者魔藥的過(guò)程,可以實(shí)現(xiàn)自動(dòng)喝藥。這是基本的外掛過(guò)程。

2.C++MFC DLL的編寫(xiě):從其他語(yǔ)言過(guò)來(lái)可能不知道C++寫(xiě)DLL。C++DLL有很多種方式去寫(xiě)。這里我就介紹MFC DLL。它最容易上手。DLL的用處是什么呢??其它用處我就不說(shuō)了,只說(shuō)在外掛中什么作用。在外掛中我們需要進(jìn)程注入。前面講過(guò),每個(gè)程序都有一個(gè)自己私有的4G進(jìn)程空間(32位系統(tǒng),0x00000000~0x7FFFFFFF空間屬于應(yīng)用程序的空間,高地址空間是屬于操作系統(tǒng)的),起到保護(hù)進(jìn)程的作用。那么我們?cè)趺纯刂屏韨€(gè)一程序呢??這時(shí)候我們就要想到將我們的代碼放到被控制的進(jìn)程空間中去,可是正常情況下,在一個(gè)程序中正常情況下是訪問(wèn)不到另一個(gè)程序進(jìn)程空間的。這時(shí)候我們可以用進(jìn)程注入的方式將我們的DLL注入到游戲進(jìn)程空間中去。我比較常用的兩種方式其一是通過(guò)WriteProcessMemory的方式直接寫(xiě)進(jìn)去,另一種方式是通過(guò)鉤子的形式注入。這兩種注入方式在后面的章節(jié)中再做介紹。開(kāi)始去寫(xiě)一個(gè)DLL在項(xiàng)目解決方案上面添加項(xiàng)目(我用的是vs2012).然后選擇C++,在選擇MFC,選擇MFC DLL.在源文件后面添加一個(gè)add方法;

int add(int a,int b){
 return a+b;
}

然后一步非常重要需要暴露出來(lái)。在def文件中放入這個(gè)函數(shù)名稱(chēng)

def中的代碼是:

游戲開(kāi)發(fā)的c++框架(游戲外掛開(kāi)發(fā)之C/C++內(nèi)聯(lián)匯編代碼和DLL)

; MFCLibrary1.def : 聲明 DLL 的模塊參數(shù)。
LIBRARY
EXPORTS
 ; 此處可以是顯式導(dǎo)出
 add

這樣就將add函數(shù)暴露到了DLL外面。這樣在exe中就可以調(diào)用了;

exe程序中的調(diào)用代碼如下:

// ASMTest.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//
#include "stdafx.h"
#pragma comment(lib,"MFCLibrary1.lib")
extern int add(int a,int b);
int main(int argc, _TCHAR* argv[])
{
 int re=3;
 re=add(1,3);//調(diào)用add方法
 printf("%d",re);
 scanf_s("%d",&re);//純粹為了停頓查看控制臺(tái)輸出的結(jié)果
 return 0;
}
//int add(int a,int b){
//
// _asm{//匯編代碼塊
// mov eax,a
// add eax,b
// mov b,eax
// 
// }
// return b;
//}
#pragma comment(lib,"MFCLibrary1.lib")這是其中一種調(diào)用方式。別忘了聲明extern int add(int a,int b);否則找不到add方法。
這樣,實(shí)現(xiàn)了一個(gè)DLL和對(duì)DLL的調(diào)用。為后面注入DLL做好鋪墊。

作者:egojit

原文
:https://www.cnblogs.com/egojit/archive/2013/06/15/3135607.html

游戲開(kāi)發(fā)的c++框架(游戲外掛開(kāi)發(fā)之C/C++內(nèi)聯(lián)匯編代碼和DLL)

熱門(mén)課程推薦

熱門(mén)資訊

請(qǐng)綁定手機(jī)號(hào)

x

同學(xué)您好!

您已成功報(bào)名0元試學(xué)活動(dòng),老師會(huì)在第一時(shí)間與您取得聯(lián)系,請(qǐng)保持電話(huà)暢通!
確定