======================================================
注:本文源代码点此下载
======================================================
在开始进入正题前先罗嗦几句:
1、本人也刚学delphi不久,也刚通过《诛仙》游戏的绝大部分call不久。所以在以下所说所列举的例子并不算是名门正中的写法,如有不当,请各位原谅。
2、本人所学基本都是在“漆黑一片”中自己摸索出来的。也正因如此,因而深感各位新手想入门但又无处可问的无奈心情。所以将在下面为各位新手较详细地列举2个call的应用例子。希望大家不要象我一样走那么多的弯路。更希望论坛的各位老大能多多开源,多点无私的奉献。
抗日时期,中国之所以能屡屡打败强大的帝国,就是因为有大多数国人的无私奉献和团结一致的精神!
......
废话一堆后进入正题,下面我将会通过《诛仙》游戏分几段讲述有参数call、无参数call的调用;call在游戏更新后,自己如何找回入口地址;以及《诛仙》游戏中几个基址间的关系。
第一讲 --- 《诛仙》的基址
在论坛中看过相关帖子的朋友不难发现《诛仙》有三个所谓的基址:基址1:$12f82c基址2:$9045ec基址3:$900adc
其中它们之间的关系如下:[$12f82c]=$9045ec 、 $9045ec=[$900adc+1c]
之所以一开始就先说这个,是想希望大家学会在游戏更新后,如何快速地找到新的,适合自己习惯的有用基址。从上面关系不难看出。$12f82c是三个基址中最为稳定的一个,事实上在6.19、7.3更新时它就没,而其他2个都变了。当然如果你本身是用$12f82c这个做基址的也就免去了不少麻烦。不过我可以证实这个基址1并不能在大部分的环境下(winxp、win2000等)通过,如果不是只做给自己一个用的,最好不用这基址。
我就选用了基址2:$9045ec。因为[$12f82c]=$9045ec,所以当游戏更新了基址时,只要用ce看看[$12f82c]=?就ok了,明白了吗?(当然这并不绝对,但大部分是可行的啦,除非游戏真的动大手术啦)
而基址3:$900adc则是用于call里面的(大家看看《诛仙》call地址公布就知道这地址的重要性了),所以一定要学会怎找到这基址。
方法就是用ce跟踪[$12f82c]=?这个“?”地址是啥(现在是$9045ec),再根据“mov ecx, [eax+1c]”查看 eax的值(现在是$9045d0),最后查找$9045d0 得到 $900adc,ok?
第二讲 --- 《诛仙》的死亡回城call(无参数call)
为了大家方便学习,我一次性把整个讲解的实例程序打包贴出来,里面包括了角色基本信息的读取(含名字);无参数call(死亡回城)调用;有参数call(技能攻击)调用(仅以重击为例)。
许多新手也象我当初一样,会问论坛怎没有一个无参数call的例子。其实有参数和无参数call的调用是一样的。我就用《诛仙》的死亡回城call作为无参数call的实例,其中关键过程如下:
......
// ---- 定义参数指针
type
p1_str = packed record
param1: dword;
param2: dword;
end;
pp1_str = ^p1_str;
......
//打开游戏进程并一次性申请注入空间
procedure tform1.formcreate(sender: tobject);
begin
myhwnd:=findwindow(nil, 'element client');
getwindowthreadprocessid(myhwnd, @threadid);
hprocess_n := openprocess(process_all_access, false, threadid);
if hprocess_n = 0 then
begin
messagebox(handle, ' 请退出先登录运行《诛仙》游戏。 ','提示',mb_ok+mb_iconerror);
exit;
end;
base0:=$9045ec;// 基址
memsize:=128;// 128的空间已足够,无须4096这么浪费
threadadd := virtualallocex(hprocess_n, nil, memsize, mem_commit, page_readwrite);
paramadd := virtualallocex(hprocess_n, nil, 20, mem_commit, page_readwrite);
end;
.....
//一次性释放空间
procedure tform1.formdestroy(sender: tobject);
begin
virtualfreeex(hprocess_n, threadadd, memsize, mem_release);
virtualfreeex(hprocess_n, paramadd, 20, mem_release);
closehandle(hprocess_n);
end;
.....
//call注入
procedure injectfunc(func: pointer; param: pointer; paramsize: dword);
var
hthread: thandle;
lpnumberofbytes: dword;
begin
if hprocess_n0 then
begin
injectfunc(@mycall1, @myparam, paramsum);
end;
end;
.....
//死亡后按这按钮能回城
procedure tform1.button2click(sender: tobject);
begin
retcity;
end;
.....
第三讲 --- 《诛仙》的技能攻击call(有参数call)
有了上面无参数call做基础,有参数call就好做了,下面以《诛仙》“重击”技能攻击call为例,其中关键过程如下:
......
// ---- 定义参数指针
type
p1_str = packed record
param1: dword;
param2: dword;
end;
pp1_str = ^p1_str;
......
//打开游戏进程并一次性申请注入空间
procedure tform1.formcreate(sender: tobject);
begin
myhwnd:=findwindow(nil, 'element client');
getwindowthreadprocessid(myhwnd, @threadid);
hprocess_n := openprocess(process_all_access, false, threadid);
if hprocess_n = 0 then
begin
messagebox(handle, ' 请退出先登录运行《诛仙》游戏。 ','提示',mb_ok+mb_iconerror);
exit;
end;
base0:=$9045ec;// 基址
memsize:=128;// 128的空间已足够,无须4096这么浪费
threadadd := virtualallocex(hprocess_n, nil, memsize, mem_commit, page_readwrite);
paramadd := virtualallocex(hprocess_n, nil, 20, mem_commit, page_readwrite);
end;
.....
//一次性释放空间
procedure tform1.formdestroy(sender: tobject);
begin
virtualfreeex(hprocess_n, threadadd, memsize, mem_release);
virtualfreeex(hprocess_n, paramadd, 20, mem_release);
closehandle(hprocess_n);
end;
.....
//call注入
procedure injectfunc(func: pointer; param: pointer; paramsize: dword);
var
hthread: thandle;
lpnumberofbytes: dword;
begin
if hprocess_n0 then
begin
injectfunc(@mycall8, @myparam, paramsum);
end;
end;
.....
//按这按钮能用“重击”技能攻击怪
procedure tform1.button3click(sender: tobject);
begin
jnid:=$da;// 这里举例用“重击”的id号为例
jineng;
end;
.....
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/