⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 autoassembler.pas.svn-base

📁 这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望对大家有帮助
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
            if not DBKReadWrite then raise exception.Create('You need to use kernelmode read/writeprocessmemory if you want to use KALLOC');

            if DarkByteKernel=0 then
              raise exception.Create('Sorry, but without the driver KALLOC will not function');

            //syntax: kalloc(x,size)    x=variable name size=bytes
            //kallocate memory
            a:=pos('(',currentline);
            b:=pos(',',currentline);
            c:=pos(')',currentline);

            if (a>0) and (b>0) and (c>0) then
            begin
              s1:=copy(currentline,a+1,b-a-1);
              s2:=copy(currentline,b+1,c-b-1);

              val('$'+s1,j,a);
              if a=0 then raise exception.Create(s1+' is not a valid identifier');

              varsize:=length(s1);

              //check for duplicate identifiers
              j:=0;
              while (j<length(kallocs)) and (length(kallocs[j].varname)>varsize) do
              begin
                if kallocs[j].varname=s1 then
                  raise exception.Create('The identifier '+s1+' has already been declared');

                inc(j);
              end;

              j:=length(kallocs);//quickfix

              setlength(kallocs,length(kallocs)+1);

              //longest varnames first so the rename of a shorter matching var wont override the longer one
              //move up the other kallocs so I can inser this element (A linked list might have been better)
              for k:=length(kallocs)-1 downto j+1 do
                kallocs[k]:=kallocs[k-1];

              kallocs[j].varname:=s1;
              kallocs[j].size:=StrToInt(s2);

              setlength(assemblerlines,length(assemblerlines)-1);   //don't bother with this in the 2nd pass
              continue;
            end else raise exception.Create('Wrong syntax. kalloc(identifier,sizeinbytes)');
          end;

          //replace identifiers with values so the assemble error check doesnt crash on that
          for j:=0 to length(kallocs)-1 do
            currentline:=replacetoken(currentline,kallocs[j].varname,'00000000');

          {$endif}

          //check for assembler errors
          //address

          if currentline[length(currentline)]=':' then
          begin
            try
              ok1:=false;
              for j:=0 to length(labels)-1 do
                if currentline=labels[j].labelname+':' then
                begin
                  labels[j].assemblerline:=length(assemblerlines)-1;
                  ok1:=true;
                  continue;
                end;

              if ok1 then continue; //no check

              try
                j:=symhandler.getAddressFromName(copy(currentline,1,length(currentline)-1));
              except
                currentline:=inttohex(symhandler.getaddressfromname(copy(currentline,1,length(currentline)-1)),8)+':';
                assemblerlines[length(assemblerlines)-1]:=currentline;
              end;

              continue; //next line
            except
              raise exception.Create('This address specifier is not valid');
            end;
          end;

          //replace label references with 00000000 so the assembler check doesn't complain about it
          for j:=0 to length(labels)-1 do
            currentline:=replacetoken(currentline,labels[j].labelname,'00000000');

          try
            //replace identifiers in the line with their address
            if not assemble(currentline,currentaddress,assembled[0].bytes) then raise exception.Create('bla');
          except
            raise exception.Create('This instruction can''t be compiled');
          end;

        finally
          inc(i);
        end;

      except
        on E:exception do
          raise exception.Create('Error in line '+IntToStr(i+1)+' ('+currentline+')'+' :'+e.Message);

      end;
    end;

    if length(addsymbollist)>0 then
    begin
      //now scan the addsymbollist entries for allocs and labels and see if they exist
      for i:=0 to length(addsymbollist)-1 do
      begin
        ok1:=false;
        for j:=0 to length(allocs)-1 do  //scan allocs
          if uppercase(addsymbollist[i])=uppercase(allocs[j].varname) then
          begin
            ok1:=true;
            break;
          end;

        if not ok1 then //scan labels
          for j:=0 to length(labels)-1 do
            if uppercase(addsymbollist[i])=uppercase(labels[j].labelname) then
            begin
              ok1:=true;
              break;
            end;

        if not ok1 then raise exception.Create(addsymbollist[i]+' was supposed to be added to the symbollist, but it isn''t declared');
      end;
    end;

    //check to see if the addresses are valid (label, alloc, define)
    if length(createthread)>0 then
      for i:=0 to length(createthread)-1 do
      begin
        ok1:=true;

        try
          testdword:=symhandler.getAddressFromName(createthread[i]);
        except
          ok1:=false;
        end;

        if not ok1 then
          for j:=0 to length(labels)-1 do
            if uppercase(labels[j].labelname)=uppercase(createthread[i]) then
            begin
              ok1:=true;
              break;
            end;

        if not ok1 then
          for j:=0 to length(allocs)-1 do
            if uppercase(allocs[j].varname)=uppercase(createthread[i]) then
            begin
              ok1:=true;
              break;
            end;

        {$ifndef net}
        if not ok1 then
          for j:=0 to length(kallocs)-1 do
            if uppercase(kallocs[j].varname)=uppercase(createthread[i]) then
            begin
              ok1:=true;
              break;
            end;
        {$endif}

        if not ok1 then
          for j:=0 to length(defines)-1 do
            if uppercase(defines[j].name)=uppercase(createthread[i]) then
            begin
              try
                testdword:=symhandler.getAddressFromName(defines[j].whatever);
                ok1:=true;
              except
              end;
              break;
            end;

        if not ok1 then raise exception.Create('The address in createthread('+createthread[i]+') is not valid');

      end;

    if length(loadbinary)>0 then
      for i:=0 to length(loadbinary)-1 do
      begin
        ok1:=true;

        try
          testdword:=symhandler.getAddressFromName(loadbinary[i].address);
        except
          ok1:=false;
        end;

        if not ok1 then
          for j:=0 to length(labels)-1 do
            if uppercase(labels[j].labelname)=uppercase(loadbinary[i].address) then
            begin
              ok1:=true;
              break;
            end;

        if not ok1 then
          for j:=0 to length(allocs)-1 do
            if uppercase(allocs[j].varname)=uppercase(loadbinary[i].address) then
            begin
              ok1:=true;
              break;
            end;

        {$ifndef net}
        if not ok1 then
          for j:=0 to length(kallocs)-1 do
            if uppercase(kallocs[j].varname)=uppercase(loadbinary[i].address) then
            begin
              ok1:=true;
              break;
            end;
        {$endif}

        if not ok1 then
          for j:=0 to length(defines)-1 do
            if uppercase(defines[j].name)=uppercase(loadbinary[i].address) then
            begin
              try
                testdword:=symhandler.getAddressFromName(defines[j].whatever);
                ok1:=true;
              except
              end;
              break;
            end;

        if not ok1 then raise exception.Create('The address in loadbinary('+loadbinary[i].address+','+loadbinary[i].filename+') is not valid');

      end;


    if syntaxcheckonly then
    begin
      result:=true;
      exit;
    end;

    if popupmessages and (messagedlg('This code can be injected. Are you sure?',mtConfirmation	,[mbyes,mbno],0)<>mryes) then exit;

    //allocate the memory
    //first find out how much I should allocate
    if length(allocs)>0 then
    begin
      x:=0;
      for i:=0 to length(allocs)-1 do
       inc(x,allocs[i].size);

      allocs[0].address:=dword(virtualallocex(processhandle,nil,x,MEM_COMMIT,page_execute_readwrite));

      for i:=1 to length(allocs)-1 do
        allocs[i].address:=allocs[i-1].address+allocs[i-1].size;
    end;

    {$ifndef net}
    //kernel alloc
    if length(kallocs)>0 then
    begin
      x:=0;
      for i:=0 to length(kallocs)-1 do
       inc(x,kallocs[i].size);

      kallocs[0].address:=dword(KernelAlloc(x));

      for i:=1 to length(kallocs)-1 do
        kallocs[i].address:=kallocs[i-1].address+kallocs[i-1].size;
    end;
    {$endif}

    //-----------------------2nd pass------------------------
    setlength(assembled,0);
    for i:=0 to length(assemblerlines)-1 do
    begin
      currentline:=assemblerlines[i];

      tokenize(currentline,tokens);
      //if alloc then replace with the address
      for j:=0 to length(allocs)-1 do
        currentline:=replacetoken(currentline,allocs[j].varname,IntToHex(allocs[j].address,8));

      //if kalloc then replace with the address
      for j:=0 to length(kallocs)-1 do
        currentline:=replacetoken(currentline,kallocs[j].varname,IntToHex(kallocs[j].address,8));

      for j:=0 to length(defines)-1 do
        currentline:=replacetoken(currentline,defines[j].name,defines[j].whatever);


      ok1:=false;
      if currentline[length(currentline)]<>':' then //if it's not a definition then
      for j:=0 to length(labels)-1 do
        if tokencheck(currentline,labels[j].labelname) then
        begin
          if not labels[j].defined then
          begin
            //the address hasn't been found yet
            //this is the part that causes those nops after a short jump below the current instruction

            //close
            s1:=replacetoken(currentline,labels[j].labelname,IntToHex(currentaddress,8));

            //far and big
            //FFFFF, goes over the $FF boundary, and $FFFF boundary, and is a big value (address)\
            currentline:=replacetoken(currentline,labels[j].labelname,IntToHex(currentaddress+$FFFFF,8));

            setlength(assembled,length(assembled)+1);
            assembled[length(assembled)-1].address:=currentaddress;
            assemble(currentline,currentaddress,assembled[length(assembled)-1].bytes);
            a:=length(assembled[length(assembled)-1].bytes);

            assemble(s1,currentaddress,assembled[length(assembled)-1].bytes);
            b:=length(assembled[length(assembled)-1].bytes);

            if a>b then //pick the biggest one
              assemble(currentline,currentaddress,assembled[length(assembled)-1].bytes);

            setlength(labels[j].references,length(labels[j].references)+1);
            labels[j].references[length(labels[j].references)-1]:=length(assembled)-1;

            setlength(labels[j].references2,length(labels[j].references2)+1);
            labels[j].references2[length(labels[j].references2)-1]:=i;

            inc(currentaddress,length(assembled[length(assembled)-1].bytes));
            ok1:=true;
          end else currentline:=replacetoken(currentline,labels[j].labelname,IntToHex(labels[j].address,8));

          break;
        end;

      if ok1 then continue;

      if currentline[length(currentline)]=':' then
      begin
        ok1:=false;
        for j:=0 to length(labels)-1 do
        begin
          if i=labels[j].assemblerline then
          begin
            labels[j].address:=currentaddress;
            labels[j].defined:=true;
            ok1:=true;

            //fill in the undefined opcodes
            for k:=0 to length(labels[j].references)-1 do
            begin
              a:=length(assembled[labels[j].references[k]].bytes); //original size of the assembled code
              s1:=replacetoken(assemblerlines[labels[j].references2[k]],labels[j].labelname,IntToHex(labels[j].address,8));
              assemble(s1,assembled[labels[j].references[k]].address,assembled[labels[j].references[k]].bytes);

              b:=length(assembled[labels[j].references[k]].bytes); //new size

              setlength(assembled[labels[j].references[k]].bytes,a);
              //fill the difference with nops (not the most efficient approach, but it should work)
              for l:=b to a-1 do
                assembled[labels[j].references[k]].bytes[l]:=$90;
            end;


            break;
          end;
        end;
        if ok1 then continue;

        try
          currentaddress:=symhandler.getAddressFromName(copy(currentline,1,length(currentline)-1));
          continue; //next line
        except
          raise exception.Create('This address specifier is not valid');
        end;
      end;


      setlength(assembled,length(assembled)+1);
      assembled[length(assembled)-1].address:=currentaddress;
      assemble(currentline,currentaddress,assembled[length(assembled)-1].bytes);

      inc(currentaddress,length(assembled[length(assembled)-1].bytes));
    end;


    ok2:=true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -