首页  编辑  

一个游戏修改程序 [ 英雄无敌 ]

Tags: /超级猛料/Alogrith.算法和数据结构/源代码/   Date Created:

跨越内存禁区修改游戏数据(2001年第2期)

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]:='Orrin';                heros[1]:='Valeska';                heros[2]:='Edric';                heros[3]:='Sylvia';

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

heros[8]:='Rion';                heros[9]:='Adela';                heros[10]:='Cuthbert';  heros[11]:='Adelaide';

heros[12]:='Ingham';   heros[13]:='Sanya';        heros[14]:='Loynis';        heros[15]:='Caitlin';

heros[16]:='Mephala';        heros[17]:='Ufretin';        heros[18]:='Jenova';        heros[19]:='Ryland';

heros[20]:='Thorgrim';        heros[21]:='Ivor';                heros[22]:='Clancy';        heros[23]:='Kyrre';

heros[24]:='Coronius';        heros[25]:='Uland';                heros[26]:='Elleshar';        heros[27]:='Gem';

heros[28]:='Malcom';        heros[29]:='Melodia';        heros[30]:='Alagar';        heros[31]:='Aeris';

heros[32]:='Piquedram';        heros[33]:='Thane';                heros[34]:='Josephine';        heros[35]:='Neela';

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

heros[40]:='Astral';                heros[41]:='Halon';                heros[42]:='Serena';        heros[43]:='Daremyth';

heros[44]:='Theodorus';        heros[45]:='Solmyr';        heros[46]:='Cyra';                heros[47]:='Aine';

heros[48]:='Fiona';                heros[49]:='Rashka';        heros[50]:='Marius';        heros[51]:='Ignatius';

heros[52]:='Octavia';        heros[53]:='Calh';                heros[54]:='Pyre';                heros[55]:='Nymus';

heros[56]:='Ayden';                heros[57]:='Xyron';                heros[58]:='Axsis';                heros[59]:='Olema';

heros[60]:='Calid';                heros[61]:='Ash';                heros[62]:='Zydar';                heros[63]:='Xarfax';

heros[64]:='Straker';        heros[65]:='Vokial';                heros[66]:='Moandor';        heros[67]:='Charna';

heros[68]:='TamikaIsra';        heros[69]:='Isra';                heros[70]:='Clavius';        heros[71]:='Galthran';

heros[72]:='Septienna';        heros[73]:='Aislinn';        heros[74]:='Sandro';        heros[75]:='Nimbus';

heros[76]:='Thant';                heros[77]:='Xsi';                heros[78]:='Vidomina';        heros[79]:='Nagash';

heros[80]:='Lorelei';        heros[81]:='Arlach';        heros[82]:='Dace';                heros[83]:='Ajit';

heros[84]:='Damacon';        heros[85]:='Gunnar';        heros[86]:='Synca';                heros[87]:='Shakti';

heros[88]:='Alamar';        heros[89]:='Jaegar';                heros[90]:='Malekith';        heros[91]:='Jeddite';

heros[92]:='Geon';                heros[93]:='Deemer';        heros[94]:='Sephinroth';        heros[95]:='Darkstorn';

heros[96]:='Yog';                heros[97]:='Gurnisson';        heros[98]:='Jabarkas';        heros[99]:='Shiva';

heros[100]:='Gretchin';        heros[101]:='Krellion';        heros[102]:='Crag Hack';heros[103]:='Tyraxor';

heros[104]:='Gird';                heros[105]:='Vey';                heros[106]:='Dessa';        heros[107]:='Terek';

heros[108]:='Zubin';        heros[109]:='Gundula';        heros[110]:='Oris';                heros[111]:='Saurug';

heros[112]:='Bron';                heros[113]:='Drakon';        heros[114]:='Wystan';        heros[115]:='Tazar';

heros[116]:='Alkin';        heros[117]:='Korbac';        heros[118]:='Gerwulf';        heros[119]:='Broghild';

heros[120]:='Mirlanda';        heros[121]:='Rosic';        heros[122]:='Voy';                heros[123]:='Verdish';

heros[124]:='Merist';        heros[125]:='Styg';                heros[126]:='Andra';        heros[127]:='Tiva';

heros[128]:='Pasis';                heros[129]:='Thunar';        heros[130]:='Ignissa';        heros[131]:='Lacus';

heros[132]:='Monere';        heros[133]:='Erdamon';        heros[134]:='Fiur';                heros[135]:='Kalt';

heros[136]:='Luna';                heros[137]:='Brissa';        heros[138]:='Ciele';                heros[139]:='Labetha';

heros[140]:='Inteus';        heros[141]:='Aenain';        heros[142]:='Gelare';        heros[143]:='Grindan';

heros[144]:='Sir Mullich';heros[145]:='Adrienne';heros[146]:='Catherine';        heros[147]:='Dracon';

heros[148]:='Gelu';                heros[149]:='Kilgor';        heros[150]:='Lord Haart';heros[151]:='Mutare';

heros[152]:='Roland';        heros[153]:='Mutare Drake';heros[154]:='Boragus';heros[155]:='Xeron';

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,'Heroes of Might and Magic III: Armageddon''s Blade');

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

      if winhwnd=0 then  showmessage('Heroes III is not running');

  threadId:=GetWindowThreadProcessId(winhwnd,@pId) ;

            if threadId=0 then    showmessage('not find id');

  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('Write mem Error');

   end;

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

   begin

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

             4, lpNumberOfBytesWritten) then

             showmessage('Write mem Error');

   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)+'Write mem Error');

  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)+'Read mem Error');

  newdistance[0]:=olddistance[0];

  newdistance[1]:=olddistance[1];

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

             2, lpNumberOfBytesWritten) then

             showmessage(inttostr(getlasterror)+'Write mem Error');

 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)+'Write mem Error');

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.