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

📄 autoassembler.pas

📁 冒险岛吸怪源码UCE的制作材料 用于冒险岛游戏的外挂
💻 PAS
📖 第 1 页 / 共 2 页
字号:

          val('$'+copy(currentline,1,length(currentline)-1),j,e);
          if e>0 then
          begin
            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;



    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;


  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));


    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
          //

          //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:=StrToInt('$'+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;


  ok1:=true;
  ok2:=true;

  for i:=0 to length(fullaccess)-1 do
  begin
    virtualprotectex(processhandle,pointer(fullaccess[i].address),fullaccess[i].size,PAGE_EXECUTE_READWRITE,op);

    if (fullaccess[i].address>80000000) and (DarkByteKernel<>0) then
      MakeWritable(fullaccess[i].address,((fullaccess[i].size div 4096)+1)*4096,false);
  end;


  //we're still here so, inject it
  for i:=0 to length(assembled)-1 do
  begin
    virtualprotectex(processhandle,pointer(assembled[i].address),length(assembled[i].bytes),PAGE_EXECUTE_READWRITE,op);
    ok1:=WriteProcessMemory(processhandle,pointeR(assembled[i].address),@assembled[i].bytes[0],length(assembled[i].bytes),op2);
    virtualprotectex(processhandle,pointer(assembled[i].address),length(assembled[i].bytes),op,op2);

    if not ok1 then ok2:=false;
  end;

  if not ok2 then
  begin
    if popupmessages then showmessage('Not all instructions could be injected')
  end
  else
  begin
    if ceallocarray<>nil then
    begin
      //see if all allocs are deallocated
      if length(dealloc)=length(ceallocarray) then //free everything
      begin
        baseaddress:=$FFFFFFFF;

        for i:=0 to length(dealloc)-1 do
        begin
          if ceallocarray[i].address<baseaddress then
            baseaddress:=dealloc[i];
        end;
        virtualfreeex(processhandle,pointer(baseaddress),0,MEM_RELEASE);
      end;


      setlength(ceallocarray,length(allocs));
      for i:=0 to length(allocs)-1 do
        ceallocarray[i]:=allocs[i];
    end;


    //check the addsymbollist array and deletesymbollist array

    //first delete
    for i:=0 to length(deletesymbollist)-1 do
      symhandler.DeleteUserdefinedSymbol(deletesymbollist[i]);

    //now scan the addsymbollist array and add them to the userdefined list
    for i:=0 to length(addsymbollist)-1 do
    begin
      ok1:=false;
      for j:=0 to length(allocs)-1 do
        if uppercase(addsymbollist[i])=uppercase(allocs[j].varname) then
        begin
          try
            symhandler.DeleteUserdefinedSymbol(addsymbollist[i]); //delete old one so you can add the new one
            symhandler.AddUserdefinedSymbol(allocs[j].address,addsymbollist[i]);
            ok1:=true;
          except
            //don't crash when it's already defined or address=0
          end;

          break;
        end;

      if not ok1 then
        for j:=0 to length(labels)-1 do
          if uppercase(addsymbollist[i])=uppercase(labels[j].labelname) then
          begin
            try
              symhandler.DeleteUserdefinedSymbol(addsymbollist[i]); //delete old one so you can add the new one
              symhandler.AddUserdefinedSymbol(labels[j].address,addsymbollist[i]);
              ok1:=true;
            except
              //don't crash when it's already defined or address=0
            end;

          end;
    end;


    if popupmessages then
    begin
      s1:='';
      for i:=0 to length(allocs)-1 do
        s1:=s1+#13#10+allocs[i].varname+'='+IntToHex(allocs[i].address,8);

      if length(kallocs)>0 then
      begin
        s1:=#13#10+'The following kernel addresses where allocated:';
        for i:=0 to length(kallocs)-1 do
          s1:=s1+#13#10+kallocs[i].varname+'='+IntToHex(kallocs[i].address,8);
      end;

      showmessage('The code injection was successfull'+s1);
    end;
  end;

  result:=ok2;

  finally
    for i:=0 to length(assembled)-1 do
      setlength(assembled[i].bytes,0);

    setlength(assembled,0);
    tokens.free;
  end;
end;


procedure getenableanddisablepos(code:tstrings;var enablepos,disablepos: integer);
var i,j: integer;
    currentline: string;
begin
  enablepos:=-1;
  disablepos:=-1;

  for i:=0 to code.Count-1 do
  begin
    currentline:=code[i];
    j:=pos('//',currentline);
    if j>0 then
      currentline:=copy(currentline,1,j-1);

    while (length(currentline)>0) and (currentline[1]=' ') do currentline:=copy(currentline,2,length(currentline)-1);
    while (length(currentline)>0) and (currentline[length(currentline)]=' ') do currentline:=copy(currentline,1,length(currentline)-1);

    if length(currentline)=0 then continue;
    if copy(currentline,1,2)='//' then continue; //skip

    if (uppercase(currentline))='[ENABLE]' then
    begin
      if enablepos<>-1 then
      begin
        enablepos:=-2;
        exit;
      end;

      enablepos:=i;
    end;

    if (uppercase(currentline))='[DISABLE]' then
    begin
      if disablepos<>-1 then
      begin
        disablepos:=-2;
        exit;
      end;

      disablepos:=i;
    end;

  end;
end;


function autoassemble(code: Tstrings; popupmessages,enable,syntaxcheckonly: boolean;var CEAllocarray: TCEAllocArray): boolean; overload;
var tempstrings: tstringlist;
    i,j: integer;
    currentline: string;
    enablepos,disablepos: integer;
begin
  getenableanddisablepos(code,enablepos,disablepos);

  if enablepos=-2 then raise exception.Create('You can only have one enable section');
  if disablepos=-2 then raise exception.Create('You can only have one disable section');

  tempstrings:=tstringlist.create;
  try
    if (enablepos=-1) and (disablepos=-1) then
    begin
      //everything
      tempstrings.AddStrings(code);
    end
    else
    begin
      if (enablepos=-1) then raise exception.Create('You havn''t specified a enable section');
      if (disablepos=-1) then raise exception.Create('You havn''t specified a disable section');

      if enable then
      begin
        if enablepos>disablepos then
        begin
          //copy everything from enablepos to end
          for i:=enablepos+1 to code.count-1  do
            tempstrings.add(code[i]);
        end
        else
        begin
          for i:=enablepos+1 to disablepos-1 do
            tempstrings.add(code[i]);
        end;
      end
      else
      begin
        if disablepos>enablepos then
        begin
          //copy everything from disablepos to end
          for i:=disablepos+1 to code.count-1  do
            tempstrings.add(code[i]);
        end
        else
        begin
          for i:=disablepos+1 to enablepos-1 do
            tempstrings.add(code[i]);
        end;
      end;
    end;

    result:=autoassemble2(tempstrings,popupmessages,syntaxcheckonly,ceallocarray);
  finally
    tempstrings.Free;
  end;
end;

function autoassemble(code: tstrings;popupmessages: boolean):boolean; overload;
var aa: TCEAllocArray;
begin
  setlength(aa,0);
  autoassemble(code,popupmessages,true,false,aa);
end;


end.

⌨️ 快捷键说明

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