📄 autoassembler.pas
字号:
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 + -