typedef struct
{
int len;
char text[100];
}DT;
void SText(DWORD eax1)
{
DT dstring;
strcpy(dstring.text,(char*)string);
dstring.len=strlen(string);
txtaddress=(DWORD)&dstring.text[0];
_asm
{
mov eax, eax1
call setshowmode1
call setshowmode2
push TRANSPARENT
push eax
call setshowmode3
push txtcolor
push bkcol
push txtaddress
mov ecx, y
mov edx, x
mov eax, eax1
call ShowTxtcall
}
}
然后定义一些全局变量和一个可以动态修改输出的字符串和颜色与位置的函数:
const DWORD conaddress=0x47A6CC;
const DWORD ShowTxtcall=0x4a09a0;
const DWORD setshowmode1=0x44D8B4,setshowmode2=0x41834C,setshowmode3=0x406434;
DWORD x=0x0, y=0x0,txtcolor=0x0,bkcol=0x1e00ff;
DWORD txtaddress=0x0;
char* string="传奇小外挂--By weishaoQQ:450196";
void settxt(char* strings,
DWORD X,DWORD Y,
DWORD TXTCOLOR,DWORD BKCOL)
{
string=strings;
x=X;
y=Y;
txtcolor=TXTCOLOR;
bkcol=BKCOL;
}
现在我们的屏幕输出函数已经模拟出来了,下面要做的就是改掉游戏显示屏幕坐标函数(关于这个函数地址你可以用金山游侠等工具查找很方便的)内部执行的流程,使这个函数跳转到我们的函数中来这样就可以在屏幕上无闪动的输出想输出的字符串了..
定义一个naked函数 关于naked可以去网上查查..
__declspec(naked) initST()
{
_asm
{
push eax
push edx
push ecx
push ebp//保存参数
mov eax,dword ptr[ebp-0x8] //获得我们当时eax中的值
push eax //传入eax参数
call disfunc //调用我们的函数
pop ebp //恢复堆栈
pop ecx
pop edx
pop eax
mov ecx,9
jmp conaddress //返回游戏函数继续执行
}
}
void __stdcall disfunc(DWORD eax1)
{
SText(eax1);//调用我们的函数
}
上面代码中我们看到函数中一直都需要获得当时的eax中的值,经过跟踪分析我选择0x47a6cc(返回)(显示地图坐标函数的入口偏移几个字节在这里可以在本函数第一时间内拿到eax而处理机器码量较少)处地址...
代码如下:
LRESULT CALLBACK hookproc(int ncode ,WPARAM wparam,LPARAM lparam)
{
if(KEYUP(lparam)&&ncode==HC_ACTION&&wparam==VK_HOME)
{
settxt("ShowText Testing....终于成功啦!!!",0x120,0x80,0x0,0x00ffff);
}
if(KEYUP(lparam)&&ncode==HC_ACTION&&wparam==VK_F12)
{
char buf[MAX_PATH];
::GetClassName(GetActiveWindow(),buf,MAX_PATH);
if (lstrcmpi(buf,"TFrmMain")==0)
{
_asm //改写 地址 跳转到我们的函数
{
lea eax,initST
mov ebx,0x47a6cc //写入这个地址
sub eax,ebx
mov esi,0x47a6c7
mov dword ptr[esi],0xe9 //JMP
mov dword ptr[esi+0x1],eax //合成跳转指令
}
}
}
return ::CallNextHookEx(hook,ncode,wparam,lparam);
}
现在我们的一个屏幕输出的简单内挂就完成了,根据网上提供的一些内存地址你可以给它加上更多的功能。
最后一件事情就是外挂退出时恢复机器码,以免游戏跳转到一个不可用的地址造成崩溃..
代码如下:
void revert()
{
_asm
{
mov esi,0x47A6C7
mov eax,0xb9
mov dword ptr[esi],eax
mov eax,0x09
mov dword ptr[esi+0x1],eax
}
}
到这里一个简单的传奇外挂诞生了,可以根据自己的需求进行修改,此代码功能不完全,错误难免,请自行修改!
本文原创与 传奇外挂 网 HTTP://WWW.HENZHUAI.COM
本文章原创于传奇外挂网 来源:www.henzhuai.com