日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

给网游写一个挂吧(四) – 调用游戏函数

發布時間:2024/4/11 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 给网游写一个挂吧(四) – 调用游戏函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面的文章給網游寫一個掛吧??啟動外掛上給網游寫一個掛吧??啟動外掛下將外掛啟動后,那就可以進行讀寫游戲內存和調用游戲的一些操作了。

?

讀寫內存很簡單,如果是內掛的話,因為是運行在進程內,甚至都可以使用普通的指針操作就可以了,本文介紹調用游戲內部函數的方法,這里以WOW為例解釋調用過程,方法可以在WOW 3.x上使用,大家可以建個私服試試。

?

我們知道WOW里有很多的宏,玩家可以寫一些宏做一些輔助的操作,這些宏內部是使用Lua實現的,而Lua呢又可以調用C/C++函數來訪問WOW的內部數據。WOW里,玩家只能用公開的宏,還有些宏是WOW程序自用的,也就是說,WOW的程序員用C/C++實現了游戲的內核,然后再用Lua實現周邊的輔助功能,這些宏在游戲界面上是不允許被調用的。但那里有很多我們需要的功能……

?

C調用Lua函數

LuaC是可以相互調用的,當然了,看完本系列文章以后,你甚至可以讓LuaC#C相互調用。Lua好像是基于堆棧虛擬機實現的,就是說操作數(oprand)都在堆棧上,Lua解釋器根據操作符的要求,在操作數堆棧上取相應數目的參數。比如說,要在C里調用下面這個Lua函數:

?

function f(x, y)

? return (x ^ 2 * math.sin(y)) / (1 – x)

end

?

那么在C里,調用的方法是:

1

2

3

4

5

lua_getglobal(L,?"f");

lua_pushnumber(L, x);

lua_pushnumber(L, y);

???

lua_pcall(L, 2, 1, 0);

?

具體詳情和原理請參見:Lua文檔。當然要在C#里調用Lua函數的話,說白了就是將P/Invoke技術和上面的方法結合起來就可以了。

?

C#里調用任意函數

C/C++里是可以跳轉到任意地址執行代碼,只要將一個地址顯式轉換成函數指針再調用即可,那么在C#里,方法也是類似的:

1.?????????定義一個委托,即跟在P/Invoke里調用函數指針的方式是一樣。

2.?????????使用函數Marshal.GetDelegateForFunctionPointer將給定的地址(也就是一個數字)轉換成委托的實例。

3.?????????傳入參數調用即可。

?

如果要調用的不是現有函數的話,那么可以在進程里分配一段內存,使用Marshal類里的AllocHGlobal函數來分配內存,將我們要執行的代碼以機器碼的形式寫進去,然后通過上面講的方式調用。這里介紹一個庫,可以把上面的流程簡化,BlackMagic(如果找不到的話,可以聯系我要也行,不過我不一定總是回郵件的):

源碼下載:http://www.shynd.com/public/BlackMagic.1.1.source.rar

文檔下載:http://www.shynd.com/public/BlackMagic.1.0.Doc.zip

庫下載:http://www.gamedeception.net/threads/14468-BlackMagic-Managed-Memory-Manipulation

?

BlackMagic,在進程里動態注入代碼并執行的方式如下面的代碼所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

private?void?Synchronize()

{

????while?(_magic.ReadInt((uint)Offsets.LuaThreadLock) != 0)

??? {

??????? Thread.Sleep(0);

??? }

??? ThreadSusspender.SuspendThread(MainThread);

}

?

private?void?AsmUpdateCurrentManager()

{

??? _magic.Asm.AddLine("mov EDX, {0}", CurrentManager);

??? _magic.Asm.AddLine("FS mov EAX, [0x2C]");

??? _magic.Asm.AddLine("mov EAX, [EAX]");

??? _magic.Asm.AddLine("add EAX, 8");

??? _magic.Asm.AddLine("mov [EAX], edx");

}

??????????????????????

private?void?ResumeMainThread()

{

??? ThreadSusspender.ResumeThread(MainThread);

}

?

public?void?DoString(string?lua)

{

??? Synchronize();

????uint?codeCave = _magic.AllocateMemory(0x2048);

?

??? _magic.WriteASCIIString(codeCave + 0x1024, lua);

?

??? _magic.Asm.Clear();

??? AsmUpdateCurrentManager();

?

??? _magic.Asm.AddLine("push {0}", 0);

??? _magic.Asm.AddLine("mov eax, {0}", codeCave + 0x1024);

??? _magic.Asm.AddLine("push eax");

??? _magic.Asm.AddLine("push eax");

??? _magic.Asm.AddLine("call {0}", (uint) Offsets.LuaDoString);

??? _magic.Asm.AddLine("add esp, 0xC");

??? _magic.Asm.AddLine("retn");

?

??? _magic.Asm.InjectAndExecute(codeCave);

??? _magic.FreeMemory(codeCave);

??? ResumeMainThread();

}

?

private?uint?CurrentManager

{

????get

??? {

????????return?_magic.ReadUInt(_magic.ReadUInt((uint)Offsets.ClientConnection) + (uint)Offsets.ClientManager);

??? }

}

?

26行代碼將主線程暫停,以便我們的線程修改進程的對象時,不會影響到主線程顯式的畫面。第27行在游戲進程里分配了2K字節的內存,29行將lua代碼拷貝到內存的后半段,31 – 32行做一些初始化的操作,比如清除上一次動態注入的匯編碼,32行是跟游戲相關的代碼,后面會提到。第34 – 40行插入要動態執行的代碼,而代碼的一些參數?–?主要就是數字。第42行注入和執行剛生成的代碼,第43行代碼在代碼執行完畢之后釋放內存,并在第44行恢復線程的執行。

?

而第47 – 53行代碼是獲取游戲(這里是WOW)里全局對象,因為WOW里可以從這個全局對象抓取到所有的數據?–?例如游戲的人物、障礙物之類的信息。

?

上面的代碼也演示了WOW里的一個技巧,Lua里有一個函數dostring,可以接受一段lua代碼的字符串并執行,演示的代碼也是調用luadostring函數的方法,通過lua dostring的方法可以繞過WOW對受限宏的調用控制,不過是在3.x上試的了,后面興趣點不在這里了,在4.x上就沒有看了。

?

文章寫到這里,只是把以前做內掛的技術講了一下,在國內的網站上基本上搜不到使用C#做內掛的方法,因此用幾篇文章的篇幅大概講講。內掛的缺點是,限制太多,因為是在游戲進程內加載東西,一不小心總是會被游戲檢測出來,而調用游戲內部現有函數(比如一些變態的功能)又會被服務器端檢測出封殺,所以后面會有一到兩篇文章講講做純外掛的方法,也就是不加載任何東西進入游戲進程。

?

如果大家對調試技術感興趣的話,可以考慮購買我的新書:?應用程序調試技術,這套視頻除了講解調試的技巧外,還盡量完整地講解了周邊用到的技術,這是因為調試技術要好的話,需要基礎功和背景知識扎實才行。??

總結

以上是生活随笔為你收集整理的给网游写一个挂吧(四) – 调用游戏函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。