完美国际FB飞天防封外挂的源代码

来源:百度文库 编辑:神马文学网 时间:2024/04/29 17:47:07

{前面的文章说过,完美的外挂检测一方面是注入别的程序进行检查(用瑞星的或者360的保险箱就知道了),一方面是对自己的基址进行检测.而且不是实时检测,可能是3-10分钟检测一次.要达到防封,基址不能动,那就动别的内存,由于其它的内存是不断变化的,基本不大可能做到检测,最多侦测一下几个关键点.
于是针对这个,采用代码注入的方法,找到对应的飞行在非基址内存的位置,相应修改一下,就可以达到强制飞行效果,由于注入的代码在找到内存后就还原基址中的代码,所以就可以避过封号检测.在和朋友的实际测试中,以下方法从未封号.(不排除完美知道后采取相关措施)
以下是67版本(忘记了.春节左右写的代码.),注入原理参考http://hi.baidu.com/junus/blog/item/d62a4627ac4b1000918f9dbd.html.注入的位置是内存中一段有Read+Write权限的内存片.先注入代码,读取飞行在非基址内存的位置,再还原代码.修改对应非基址内存,达到强制飞行目的.
Win Xp Sp2 + Delphi. v7平台调试通过.
Copyright@时光牧者(http://hi.baidu.com/junus ).
Email:firt123@163.com
转载请注明出处,谢谢---------时光牧者}
unit Umain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls;
type
TForm1 = class(TForm)
Timer1: TTimer;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
Label1: TLabel;
Label2: TLabel;
procedure Timer1Timer(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
Wnd:hwnd;
pid:longint;
ProHandle:THandle;
insertdd:longint;
insertad1:longint;
insertad2:longint;
insertad3:longint;
fxdd:longint;
fxaddr:int64;
code1: int64;
code2: int64;
code3: int64;
code4: int64;
codebak:int64;
Num:cardinal;
function FindproHandle():boolean;
procedure insertcode();//代码注入
procedure rebackcode();//恢复代码
procedure readadd(); //读取地址
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject);//随机标题
begin
Application.Title:=inttostr(Random(9999)) + inttostr(Random(9999));
form1.Caption:= Application.Title;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);//打开飞行
var
fxdata:integer;
begin
if FindproHandle() then
begin
if fxaddr<=1600 then//这个判断是因为可能注入后没有读取到正确基址.
begin
readadd;
if fxaddr<=1600 then
exit;
end;
fxdata:=$10;
WriteProcessMemory(ProHandle,Pointer(Form1.fxaddr),@fxdata,2,num);
CloseHandle(ProHandle);
CloseHandle(wnd);
end;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);//关闭飞行
var
fxdata:integer;
begin
if FindproHandle() then
begin
if fxaddr<=1600 then
begin
readadd;
if fxaddr<=1600 then
exit;
end;
fxdata:=$00;
WriteProcessMemory(ProHandle,Pointer(Form1.fxaddr),@fxdata,2,num);
CloseHandle(ProHandle);
CloseHandle(wnd);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//代码注入点
insertdd:=$4581C6;//4582D6;//$00004584E6;
insertad1:=$00003F3410;
insertad2:=$00003F3416;
insertad3:=$00003F341C;
//飞行地址
fxdd:=$00003F3430;
//要注入和还原的代码
code1:=$062C868B; // 原代码处 mov eax,[esi+000062c]
code2:=$3F34303589;//读地址    mov [3F3430],esi
code3:=$064da5E9;   //跳回     jmp insertdd
code4:=$E8C190FFF9B245E9;//跳到注入代码段
codebak:=$00000000;
fxaddr:=0;
num:=0;
end;
function TForm1.FindproHandle():boolean;
var
flag:boolean;
begin
num:=0;
flag:=true;
Wnd := FindWindow(nil,'Element Client');//查找窗口
GetWindowThreadProcessId(Wnd, @PID); //得到pID
//以完全访问权限打开进程句柄
ProHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
if PID=0 then
begin
showmessage('进程读取失败,可能是游戏没有启动!');
flag:=false;
end;
FindproHandle:=flag;
end;
procedure TForm1.insertcode();//代码注入
begin
WriteProcessMemory(ProHandle,Pointer(Form1.insertad1),@Form1.code1,8,num);
WriteProcessMemory(ProHandle,Pointer(Form1.insertad2),@Form1.code2,8,num);
WriteProcessMemory(ProHandle,Pointer(Form1.insertad3),@Form1.code3,8,num);
WriteProcessMemory(ProHandle,Pointer(Form1.insertdd),@Form1.code4,8,num);
end;
procedure TForm1.rebackcode();//恢复代码
begin
WriteProcessMemory(ProHandle,Pointer(Form1.insertdd),@Form1.code1,6,num);
WriteProcessMemory(ProHandle,Pointer(Form1.insertad3),@Form1.codebak,8,num);
WriteProcessMemory(ProHandle,Pointer(Form1.insertad2),@Form1.codebak,8,num);
WriteProcessMemory(ProHandle,Pointer(Form1.insertad1),@Form1.codebak,8,num);
WriteProcessMemory(ProHandle,Pointer(Form1.fxdd),@Form1.codebak,8,num);
end;
procedure TForm1.readadd();//读内存中飞行的地址
{var
fxdata:int64; }
begin
if FindproHandle() then
begin
fxaddr:=0;
//fxdata:=0;
insertcode();//代码注入
sleep(10);
//读内存的地址
readProcessMemory(ProHandle,Pointer(Form1.fxdd),@fxaddr,8,num);
//偏移后得准确地址
fxaddr:=fxaddr+$0000062c;
//读飞行的数据
//readProcessMemory(ProHandle,Pointer(fxaddr),@fxdata,4,num);
label2.Caption:='基址:' + inttostr(fxaddr)+' ';
rebackcode();//恢复代码
if fxaddr<=1600 then
begin
label2.Caption:= '基址:[' + inttostr(fxaddr)+']可能有误.请重试 ';
end;
CloseHandle(ProHandle);
CloseHandle(wnd);
end;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;
end.