網路遊戲的封包技術是大多數程式設計愛好者都比較關注的關注的問題之一,在這一篇裡就讓我們一起研究一下這乙個問題吧。
別看這是封包這一問題,但是涉及的技術範圍很廣範,實現的方式也很多(比如說apihook,vxd,winsock2都可以實現),在這裡我們不可能每種技術和方法都涉及,所以我在這裡以winsock2技術作詳細講解,就算作拋磚引玉。
apihook:
由於windows的把核心提供的功能都封裝到api裡面,所以大家要實現功能就必須通過api,換句話說就是我們要想捕獲資料封包,就必須先要得知道並且捕獲這個api,從api裡面得到封包資訊。
vxd:
直接通過控制vxd驅動程式來實現封包資訊的捕獲,不過vxd只能用於win9x。
winsock2:
winsock是windows網路程式設計介面,winsock工作在應用層,它提供與底層傳輸協議無關的高層資料傳輸程式設計介面,winsock2是winsock2.0提供的服務提供者介面,但只能在win2000下用。
好了,我們開始進入winsock2封包式程式設計吧。
首先我們要實現的是封包的捕獲:
delphi的封裝的winsock是1.0版的,很自然winsock2就用不成。如果要使用winsock2我們要對winsock2在delphi裡面做乙個介面,才可以使用winsock2。
1、如何做winsock2的介面?
1)我們要先定義winsock2.0所用得到的型別,在這裡我們以wsa_data型別做示範,大家可以舉一仿三的來實現winsock2其他型別的封裝。
我們要知道wsa_data型別會被用於wsastartup(wversionrequired: word; var wsdata: twsadata): integer;,大家會發現wsdata是引用引數,在傳入引數時傳的是變數的位址,所以我們對wsa_data做以下封裝:
const
wsadescription_len = 256;
wsasys_status_len = 128;
type
pwsa_data = ^twsa_data;
wsa_data = record
wversion: word;
whighversion: word;
szdescription: array[0..wsadescription_len] of char;
szsystemstatus: array[0..wsasys_status_len] of char;
imaxsockets: word;
imaxudpdg: word;
lpvendorinfo: pchar;
end;
twsa_data = wsa_data;
2)我們要從ws2_32.dll引入winsock2的函式,在此我們也是以wsastartup為例做函式引入:
function wsastartup(wversionrequired: word; var wsdata: twsadata): integer; stdcall;
implementation
const winsocket2 = 'ws2_32.dll';
function wsastartup; external winsocket name 'wsastartup';
通過以上方法,我們便可以對winsock2做介面,下面我們就可以用winsock2做封包捕獲了,不過首先要有一塊網絡卡。因為涉及到正在運作的網路遊戲安全問題,所以我們在這裡以ip資料報為例做封包捕獲,如果下面的某些資料型別您不是很清楚,請您查閱msdn:
1)我們要起動wsa,這時個要用到的wsastartup函式,用法如下:
integer wsastartup(
wversionrequired: word,
wsdata: twsa_data
); 2)使用socket函式得到socket控制代碼,m_hsocket:=socket(af_inet, sock_raw, ipproto_ip); 用法如下:
integer socket(af: integer,
struct: integer,
protocol: integer
); m_hsocket:=socket(af_inet, sock_raw, ipproto_ip);在程式裡m_hsocket為socket控制代碼,af_inet,sock_raw,ipproto_ip均為常量。
3)定義sock_addr型別,跟據我們的網絡卡ip給sock_addr型別附值,然後我們使用bind函式來繫結我們的網絡卡,bind函式用法如下:
type
in_addr = record
s_addr : pchar;
end;
type
tsock_addr = record
sin_family: word;
sin_port: word;
sin_addr : in_addr
sin_zero: array[0..7] of char;
end;
var
localaddr:tsock_addr;
localaddr.sin_family: = af_inet;
localaddr.sin_port: = 0;
localaddr.sin_addr.s_addr: = inet_addr('192.168.1.1'); //這裡你自己的網絡卡的ip位址,而inet_addr這個函式是winsock2的函式。
bind(m_hsocket, localaddr, sizeof(localaddr));
4)用wsaioctl來註冊wsa的輸入輸出元件,其用法如下:
integer wsaioctl(s:integer,
dwiocontrolcode : integer,
lpvinbuffer :integer,
cbinbuffer : integer,
lpvoutbuffer : integer,
cboutbuffer: integer,
lpcbbytesreturned : integer,
lpcompletionroutine : integer
); 5)下面做死迴圈,在死迴圈塊裡,來實現資料的接收。但是徇環中間要用sleep()做延時,不然程式會出錯。
6)在迴圈塊裡,用recv函式來接收資料,recv函式用法如下:
integer recv (s : integer,
buffer:array[0..4095] of byte,
length : integer,
flags : integer,
); 7)在buffer裡就是我們接收回來的資料了,如果我們想要知道資料是什麼地方發來的,那麼,我們要定義一定ip包結構,用copymemory()把ip資訊從buffer裡面讀出來就可以了,不過讀出來的是十六進製制的資料需要轉換一下。
看了封包捕獲的全過程序,對你是不是有點起發,然而在這裡要告訴大家的是封包的獲得是很容易的,但是許多遊戲的封包都是加密的,如果你想搞清楚所得到的是什麼內容還需要自己進行封包解密。
delphi外掛程式製作介紹篇
網路遊戲的封包技術是大多數程式設計愛好者都比較關注的關注的問題之一,在這一篇裡就讓我們一起研究一下這乙個問題吧。別看這是封包這一問題,但是涉及的技術範圍很廣範,實現的方式也很多 比如說apihook,vxd,winsock2都可以實現 在這裡我們不可能每種技術和方法都涉及,所以我在這裡以winsoc...
簡單外掛程式製作
外掛程式的實現方法有很多種 裡只說說其中的一種比較簡單的方法.1.啟動遊戲 2.得到程式的進的id 比較常用的方法有findwindow 得到視窗的控制代碼,更進一步你可以得到程序id,但是對於例如連連看一樣的遊戲而言,得到視窗的控制代碼就已經足夠了。其中值得注意的是,findwindow 裡面的引...
atom外掛程式製作
2016開始了自己的開發生涯,步入這個行業初時就是以前端出身,雖說現在努力往全棧開發靠攏,但在前端這個領域還是比後台熟悉。這不,平時開發的時候乙隻在用atom,也覺得他用起來還比較順手,到了新公司,我的職位還是前端開發,而且公司的 規範裡有一條就是相關的檔案都需要有一套注釋。比如這樣 的 樣式 配置...