发新话题
打印

[转载]一个英雄无敌游戏修改程序Delphi源代码

[转载]一个英雄无敌游戏修改程序Delphi源代码

信息来源:(要写信息来源)

跨越内存禁区修改游戏数据
http://www.csdn.net/magazine/source/2/Hero.doc
复制内容到剪贴板
代码:
unit uheromate;//本单元与uheromate窗体相对应

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, Menus, ComCtrls, Grids, ExtCtrls,ShellApi;

type

TModifyThread = class(TThread) //新建线程类,用于修改英雄属性页的设置

private

{ Private declarations }

protected

procedure Execute; override;

end;

TForm1 = class(TForm)

Label1: TLabel;

PageControl1: TPageControl;

TabSheet1: TTabSheet;

Label3: TLabel;

Edit1: TEdit;

UpDown1: TUpDown;

Edit2: TEdit;

UpDown2: TUpDown;

Edit3: TEdit;

UpDown3: TUpDown;

Edit4: TEdit;

UpDown4: TUpDown;

CheckBox1: TCheckBox; //英雄技能页-是否增加所有第二技能

CheckBox2: TCheckBox; //英雄技能页-是否修改四项第一技能

TabSheet2: TTabSheet;

TabSheet3: TTabSheet;

TabSheet4: TTabSheet;

ComboBox1: TComboBox; //英雄技能页-下拉框,用于选择英雄

Label2: TLabel;

B_skill: TButton; //英雄技能页-变更英雄属性按钮

B_nolimit: TButton; //机动力页-使英雄机动力无限按钮

B_allday: TButton;// 机动力页-锁定英雄机动力按钮

Timer1: TTimer;

ListBox1: TListBox;

B_okToAddArtifact: TButton; //宝物页-根据列表框中宝物修改游戏内存

B_add: TButton;//宝物页-增加宝物到列表框按钮

Label4: TLabel;

ComboBox2: TComboBox; //宝物页-宝物列表框

B_return: TButton; //返回游戏按钮

B_Remove: TButton; //宝物页-从列表框中减少宝物

procedure B_skillClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure ComboBox1Change(Sender: TObject);

procedure CheckBox2Click(Sender: TObject);

procedure B_nolimitClick(Sender: TObject);

procedure B_alldayClick(Sender: TObject);

procedure Timer1Timer(Sender: TObject);

procedure B_okToAddArtifactClick(Sender: TObject);

procedure B_addClick(Sender: TObject);

procedure B_returnClick(Sender: TObject);

procedure B_RemoveClick(Sender: TObject);

procedure FormDestroy(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

heroname:pchar; //当前修改的英雄名

heroBaseAdd,heroAdd:integer; //第一个英雄的地址和当前英雄的序号

heros:array[0..180] of pchar; //英雄名序列

isdebug:integer; //是否已用OpenProcess函数打开游戏进程

winhwnd:hwnd; //游戏窗口句柄

pId,threadId:Integer; //拥有游戏主窗口的进程和线程ID

hProcess: THandle; //用OpenProcess函数游戏进程的句柄

str1:string='锁定机动力';

str2:string='取消锁定';

implementation

{$R *.DFM}

procedure TForm1.B_skillClick(Sender: TObject);//修改英雄属性页设置

var

threadNew:TModifyThread;

begin

threadNew:=TModifyThread.Create(false);

threadNew.Execute;

if not SetForegroundWindow(winhWnd) then

showmessage(inttostr(getlasterror));

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

isdebug:=0;

heroBaseAdd:=$015c7f63; //<--光盘版$015d7f63;//硬盘版 $015c7f63;

heros[0]:=&#39;Orrin&#39;; heros[1]:=&#39;Valeska&#39;; heros[2]:=&#39;Edric&#39;; heros[3]:=&#39;Sylvia&#39;;

heros[4]:=&#39;Lord Haart(1)&#39;;heros[5]:=&#39;Sorsha&#39;; heros[6]:=&#39;Christian&#39;; heros[7]:=&#39;Tyris&#39;;

heros[8]:=&#39;Rion&#39;; heros[9]:=&#39;Adela&#39;; heros[10]:=&#39;Cuthbert&#39;; heros[11]:=&#39;Adelaide&#39;;

heros[12]:=&#39;Ingham&#39;; heros[13]:=&#39;Sanya&#39;; heros[14]:=&#39;Loynis&#39;; heros[15]:=&#39;Caitlin&#39;;

heros[16]:=&#39;Mephala&#39;; heros[17]:=&#39;Ufretin&#39;; heros[18]:=&#39;Jenova&#39;; heros[19]:=&#39;Ryland&#39;;

heros[20]:=&#39;Thorgrim&#39;; heros[21]:=&#39;Ivor&#39;; heros[22]:=&#39;Clancy&#39;; heros[23]:=&#39;Kyrre&#39;;

heros[24]:=&#39;Coronius&#39;; heros[25]:=&#39;Uland&#39;; heros[26]:=&#39;Elleshar&#39;; heros[27]:=&#39;Gem&#39;;

heros[28]:=&#39;Malcom&#39;; heros[29]:=&#39;Melodia&#39;; heros[30]:=&#39;Alagar&#39;; heros[31]:=&#39;Aeris&#39;;

heros[32]:=&#39;Piquedram&#39;; heros[33]:=&#39;Thane&#39;; heros[34]:=&#39;Josephine&#39;; heros[35]:=&#39;Neela&#39;;

heros[36]:=&#39;Torosar&#39;; heros[37]:=&#39;Fafner&#39;; heros[38]:=&#39;Rissa&#39;; heros[39]:=&#39;Iona&#39;;

heros[40]:=&#39;Astral&#39;; heros[41]:=&#39;Halon&#39;; heros[42]:=&#39;Serena&#39;; heros[43]:=&#39;Daremyth&#39;;

heros[44]:=&#39;Theodorus&#39;; heros[45]:=&#39;Solmyr&#39;; heros[46]:=&#39;Cyra&#39;; heros[47]:=&#39;Aine&#39;;

heros[48]:=&#39;Fiona&#39;; heros[49]:=&#39;Rashka&#39;; heros[50]:=&#39;Marius&#39;; heros[51]:=&#39;Ignatius&#39;;

heros[52]:=&#39;Octavia&#39;; heros[53]:=&#39;Calh&#39;; heros[54]:=&#39;Pyre&#39;; heros[55]:=&#39;Nymus&#39;;

heros[56]:=&#39;Ayden&#39;; heros[57]:=&#39;Xyron&#39;; heros[58]:=&#39;Axsis&#39;; heros[59]:=&#39;Olema&#39;;

heros[60]:=&#39;Calid&#39;; heros[61]:=&#39;Ash&#39;; heros[62]:=&#39;Zydar&#39;; heros[63]:=&#39;Xarfax&#39;;

heros[64]:=&#39;Straker&#39;; heros[65]:=&#39;Vokial&#39;; heros[66]:=&#39;Moandor&#39;; heros[67]:=&#39;Charna&#39;;

heros[68]:=&#39;TamikaIsra&#39;; heros[69]:=&#39;Isra&#39;; heros[70]:=&#39;Clavius&#39;; heros[71]:=&#39;Galthran&#39;;

heros[72]:=&#39;Septienna&#39;; heros[73]:=&#39;Aislinn&#39;; heros[74]:=&#39;Sandro&#39;; heros[75]:=&#39;Nimbus&#39;;

heros[76]:=&#39;Thant&#39;; heros[77]:=&#39;Xsi&#39;; heros[78]:=&#39;Vidomina&#39;; heros[79]:=&#39;Nagash&#39;;

heros[80]:=&#39;Lorelei&#39;; heros[81]:=&#39;Arlach&#39;; heros[82]:=&#39;Dace&#39;; heros[83]:=&#39;Ajit&#39;;

heros[84]:=&#39;Damacon&#39;; heros[85]:=&#39;Gunnar&#39;; heros[86]:=&#39;Synca&#39;; heros[87]:=&#39;Shakti&#39;;

heros[88]:=&#39;Alamar&#39;; heros[89]:=&#39;Jaegar&#39;; heros[90]:=&#39;Malekith&#39;; heros[91]:=&#39;Jeddite&#39;;

heros[92]:=&#39;Geon&#39;; heros[93]:=&#39;Deemer&#39;; heros[94]:=&#39;Sephinroth&#39;; heros[95]:=&#39;Darkstorn&#39;;

heros[96]:=&#39;Yog&#39;; heros[97]:=&#39;Gurnisson&#39;; heros[98]:=&#39;Jabarkas&#39;; heros[99]:=&#39;Shiva&#39;;

heros[100]:=&#39;Gretchin&#39;; heros[101]:=&#39;Krellion&#39;; heros[102]:=&#39;Crag Hack&#39;;heros[103]:=&#39;Tyraxor&#39;;

heros[104]:=&#39;Gird&#39;; heros[105]:=&#39;Vey&#39;; heros[106]:=&#39;Dessa&#39;; heros[107]:=&#39;Terek&#39;;

heros[108]:=&#39;Zubin&#39;; heros[109]:=&#39;Gundula&#39;; heros[110]:=&#39;Oris&#39;; heros[111]:=&#39;Saurug&#39;;

heros[112]:=&#39;Bron&#39;; heros[113]:=&#39;Drakon&#39;; heros[114]:=&#39;Wystan&#39;; heros[115]:=&#39;Tazar&#39;;

heros[116]:=&#39;Alkin&#39;; heros[117]:=&#39;Korbac&#39;; heros[118]:=&#39;Gerwulf&#39;; heros[119]:=&#39;Broghild&#39;;

heros[120]:=&#39;Mirlanda&#39;; heros[121]:=&#39;Rosic&#39;; heros[122]:=&#39;Voy&#39;; heros[123]:=&#39;Verdish&#39;;

heros[124]:=&#39;Merist&#39;; heros[125]:=&#39;Styg&#39;; heros[126]:=&#39;Andra&#39;; heros[127]:=&#39;Tiva&#39;;

heros[128]:=&#39;Pasis&#39;; heros[129]:=&#39;Thunar&#39;; heros[130]:=&#39;Ignissa&#39;; heros[131]:=&#39;Lacus&#39;;

heros[132]:=&#39;Monere&#39;; heros[133]:=&#39;Erdamon&#39;; heros[134]:=&#39;Fiur&#39;; heros[135]:=&#39;Kalt&#39;;

heros[136]:=&#39;Luna&#39;; heros[137]:=&#39;Brissa&#39;; heros[138]:=&#39;Ciele&#39;; heros[139]:=&#39;Labetha&#39;;

heros[140]:=&#39;Inteus&#39;; heros[141]:=&#39;Aenain&#39;; heros[142]:=&#39;Gelare&#39;; heros[143]:=&#39;Grindan&#39;;

heros[144]:=&#39;Sir Mullich&#39;;heros[145]:=&#39;Adrienne&#39;;heros[146]:=&#39;Catherine&#39;; heros[147]:=&#39;Dracon&#39;;

heros[148]:=&#39;Gelu&#39;; heros[149]:=&#39;Kilgor&#39;; heros[150]:=&#39;Lord Haart&#39;;heros[151]:=&#39;Mutare&#39;;

heros[152]:=&#39;Roland&#39;; heros[153]:=&#39;Mutare Drake&#39;;heros[154]:=&#39;Boragus&#39;;heros[155]:=&#39;Xeron&#39;;

end;

procedure TForm1.ComboBox1Change(Sender: TObject); //取得当前英雄的内存地址

var

OrrinBuffer:array[0..4] of byte;

i:integer;

lpNumberOfBytesWritten: DWORD;

begin

ListBox1.Items.Clear;

if isdebug=0 then //未执行OpenProcess

begin

winhwnd:=FindWindow(NIL,&#39;Heroes of Might and Magic III: Armageddon&#39;&#39;s Blade&#39;);

if winhwnd=0 then winhwnd:=FindWindow(NIL,&#39;Heroes of Might and Magic III&#39;);

if winhwnd=0 then showmessage(&#39;Heroes III is not running&#39;);

threadId:=GetWindowThreadProcessId(winhwnd,@pId) ;

if threadId=0 then showmessage(&#39;not find id&#39;);

hProcess:=OpenProcess(PROCESS_ALL_ACCESS,true, pId);

isdebug:=1;

//查找英雄数据区基地址heroBaseAdd

for i:=5 to 20 do //in least add 600000

begin

ReadProcessMemory(hProcess,ptr(heroBaseAdd), @OrrinBuffer,5, lpNumberOfBytesWritten);

//英雄数据区基地址处的值应是第一个英雄的名字:”Orrin”

if (OrrinBuffer[0]=79) and (OrrinBuffer[1]=114)

and (OrrinBuffer[2]=114) and (OrrinBuffer[3]=105)

and (OrrinBuffer[4]=110) then break;

if (i mod 2)=1 then //

heroBaseAdd:=heroBaseAdd+$10000 // <--光盘版比硬盘版多$10000

else

heroBaseAdd:=$015c7f63+$100000*(i div 2) +$30000; //硬盘版

end;

end;

//得到欲修改的英雄的序号

heroname:=Pchar(combobox1.text);

for i :=0 to 165 do

begin

if strcomp(heros[i],heroname)=0 then

begin

heroadd:=i;

exit;

end;

end;

end;

procedure TModifyThread.Execute; //修改英雄属性页的设置

var

lpBuffer: array[0..56] of byte;

four: array[0..3] of byte;

lpNumberOfBytesWritten: DWORD;

i:integer;

begin

for i := 0 to 27 do

begin

lpBuffer[i]:=3;

end;

for i := 28 to 35 do

begin

lpBuffer[i]:=i-27;

end;

lpBuffer[56]:=27; //总共有27项魔法

lpBuffer[12]:=0; //不设置招魂术

four[0]:=Form1.UpDown1.Position;

four[1]:=Form1.UpDown2.Position;

four[2]:=Form1.UpDown3.Position;

four[3]:=Form1.UpDown4.Position;

if Form1.CheckBox1.Checked=true then //增加第二技能

begin

if not WriteProcessMemory(hProcess,ptr(heroBaseAdd+heroadd*$492+$A6), @lpBuffer,

57, lpNumberOfBytesWritten) then

showmessage(&#39;Write mem Error&#39;);

end;

if Form1.CheckBox2.Checked=true then //设置第一技能

begin

if not WriteProcessMemory(hProcess,ptr(heroBaseAdd+heroadd*$492+$453), @four,

4, lpNumberOfBytesWritten) then

showmessage(&#39;Write mem Error&#39;);

end;

end;

procedure TForm1.CheckBox2Click(Sender: TObject);

begin

edit1.Enabled:=not(edit1.Enabled);

edit2.Enabled:=not(edit2.Enabled);

edit3.Enabled:=not(edit3.Enabled);

edit4.Enabled:=not(edit4.Enabled);

updown1.Enabled:=not(updown1.Enabled);

updown2.Enabled:=not(updown2.Enabled);

updown3.Enabled:=not(updown3.Enabled);

updown4.Enabled:=not(updown4.Enabled);

end;

procedure TForm1.B_nolimitClick(Sender: TObject); //无限机动力

var

newdistance: array[0..1] of byte;

lpNumberOfBytesWritten: DWORD;

begin

newdistance[0]:=$99;

newdistance[1]:=$99;

if not WriteProcessMemory(hProcess,ptr(heroBaseAdd+heroadd*$492+$2A), @newdistance,

2, lpNumberOfBytesWritten) then

showmessage(inttostr(getlasterror)+&#39;Write mem Error&#39;);

if not SetForegroundWindow(winhWnd) then

showmessage(inttostr(getlasterror));

end;

procedure TForm1.B_alldayClick(Sender: TObject); //锁定机动力

begin

if B_allday.Caption=str1 then

begin

B_allday.Caption:=str2;

Timer1.Enabled:=true;

end

else

begin

B_allday.Caption:=str1;

Timer1.Enabled:=False;

end;

end;

procedure TForm1.Timer1Timer(Sender: TObject); //锁定机动力

var

olddistance: array[0..1] of byte;

newdistance: array[0..1] of byte;

lpNumberOfBytesWritten: DWORD;

begin

if not ReadProcessMemory(hProcess,ptr(heroBaseAdd+heroadd*$492+$26), @olddistance,

2, lpNumberOfBytesWritten) then

showmessage(inttostr(getlasterror)+&#39;Read mem Error&#39;);

newdistance[0]:=olddistance[0];

newdistance[1]:=olddistance[1];

if not WriteProcessMemory(hProcess,ptr(heroBaseAdd+heroadd*$492+$2A), @newdistance,

2, lpNumberOfBytesWritten) then

showmessage(inttostr(getlasterror)+&#39;Write mem Error&#39;);

if not SetForegroundWindow(winhWnd) then

showmessage(inttostr(getlasterror));

end;

procedure TForm1.B_okToAddArtifactClick(Sender: TObject); //增加宝物

var

i:integer;

Artifact:array[0..7] of byte;

lpNumberOfBytesWritten: DWORD;

begin

Artifact[1]:=0; Artifact[2]:=0; Artifact[3]:=0;

Artifact[4]:=$FF; Artifact[5]:=$FF; Artifact[6]:=$FF; Artifact[7]:=$FF;

for i:=0 to Form1.ListBox1.Items.Count-1 do

begin

Artifact[0]:=ComboBox2.Items.IndexOf(listbox1.Items.Strings[i])+2;

if Artifact[0]<>2 then

Artifact[0]:=Artifact[0]+4;

if not WriteProcessMemory(hProcess,ptr(heroBaseAdd+heroadd*$492+$1B1+8*i), @Artifact,

8, lpNumberOfBytesWritten) then

showmessage(inttostr(getlasterror)+&#39;Write mem Error&#39;);

end;

if not SetForegroundWindow(winhWnd) then

showmessage(inttostr(getlasterror));

end;

procedure TForm1.B_addClick(Sender: TObject);

begin

ListBox1.Items.Add(ComboBox2.Text);

end;

procedure TForm1.B_returnClick(Sender: TObject);

begin

showwindow(winhwnd,SW_MAXIMIZE);

end;

 

procedure TForm1.B_RemoveClick(Sender: TObject);

begin

ListBox1.Items.Delete(ListBox1.ItemIndex);

ListBox1.ItemIndex:=0;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

if hProcess <>0 then closehandle(hProcess); //关闭句柄

end;

end.

TOP

发新话题