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