574 lines
14 KiB
ObjectPascal
574 lines
14 KiB
ObjectPascal
unit unrandomizer;
|
|
|
|
//Todo, update with new tech
|
|
|
|
{$MODE Delphi}
|
|
|
|
interface
|
|
|
|
uses windows, CEFuncProc,dialogs,classes,comctrls,LCLIntf,sysutils,formsettingsunit,NewKernelHandler, commonTypeDefs,
|
|
MemFuncs;
|
|
|
|
type Tunrandomize=class(tthread)
|
|
private
|
|
processid,processhandle: dword;
|
|
originalcode: array of record
|
|
address: dword;
|
|
code: array of byte;
|
|
end;
|
|
threaddone: boolean;
|
|
procedure save(address:dword; buf: pointer; size: integer);
|
|
procedure done;
|
|
public
|
|
progressbar: tprogressbar;
|
|
procedure execute; override;
|
|
procedure restore;
|
|
procedure showaddresses;
|
|
|
|
destructor destroy; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses MainUnit, ProcessHandlerUnit;
|
|
|
|
resourcestring
|
|
rsTheFollowingAddressesGotChanged = 'The following addresses got changed';
|
|
rsTheUnrandomizerWillCurrentlyNotWorkOn64BitApplicat = 'The unrandomizer will currently not work on 64-bit applications';
|
|
|
|
destructor TUnrandomize.destroy;
|
|
begin
|
|
if (processid=processhandlerunit.ProcessID) and (processhandle=processhandlerunit.ProcessHandle) then restore;
|
|
inherited destroy;
|
|
end;
|
|
|
|
procedure TUnrandomize.done;
|
|
begin
|
|
try
|
|
if mainform<>nil then
|
|
begin
|
|
progressbar.Hide;
|
|
progressbar.Free;
|
|
mainform.cbUnrandomizer.Enabled:=true;
|
|
end;
|
|
except
|
|
|
|
end;
|
|
threaddone:=true;
|
|
end;
|
|
|
|
procedure TUnrandomize.showaddresses;
|
|
var s: string;
|
|
i: integer;
|
|
begin
|
|
if threaddone then
|
|
begin
|
|
s:=rsTheFollowingAddressesGotChanged+':';
|
|
for i:=0 to length(originalcode)-1 do
|
|
s:=s+#13#10+inttohex(originalcode[i].address,8);
|
|
|
|
showmessage(s);
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TUnrandomize.restore;
|
|
var i: integer;
|
|
l: dword;
|
|
begin
|
|
if (processhandle<>processhandlerunit.ProcessHandle) and (processid=processhandlerunit.ProcessID) then
|
|
processhandle:=processhandlerunit.ProcessHandle; //e.g debugger
|
|
|
|
//restore the replaced code with the original
|
|
for i:=0 to length(originalcode)-1 do
|
|
begin
|
|
l:=length(originalcode[i].code);
|
|
rewritecode(processhandle,originalcode[i].address,originalcode[i].code,l);
|
|
setlength(originalcode[i].code,0);
|
|
end;
|
|
|
|
setlength(originalcode,0);
|
|
end;
|
|
|
|
procedure TUnrandomize.save(address:dword; buf: pointer; size: integer);
|
|
var i: integer;
|
|
begin
|
|
i:=length(originalcode);
|
|
|
|
setlength(originalcode,i+1);
|
|
originalcode[i].address:=address;
|
|
|
|
setlength(originalcode[i].code,size);
|
|
copymemory(originalcode[i].code,buf,size);
|
|
|
|
end;
|
|
|
|
procedure TUnrandomize.execute;
|
|
type tcodereplace=array of byte;
|
|
var memoryregion: tmemoryregions;
|
|
i,j: integer;
|
|
totalmemory: dword;
|
|
ar,aw: ptrUint;
|
|
buffer: array of byte;
|
|
totalread: dword;
|
|
|
|
vcreplace: tcodereplace;
|
|
delphireplace: tcodereplace; //also code2
|
|
msvcrtreplace: tcodereplace;
|
|
ibasicreplace: tcodereplace;
|
|
|
|
defaultreturn: integer;
|
|
incremental: boolean;
|
|
counter: pointer;
|
|
|
|
l: dword;
|
|
begin
|
|
if processhandler.is64bit then raise exception.create(rsTheUnrandomizerWillCurrentlyNotWorkOn64BitApplicat);
|
|
|
|
defaultreturn:=formsettings.unrandomizersettings.defaultreturn;
|
|
|
|
incremental:=formsettings.unrandomizersettings.incremental;
|
|
|
|
|
|
//scan the memory of the current process
|
|
processid:=processhandlerunit.ProcessID;
|
|
processhandle:=processhandlerunit.ProcessHandle;
|
|
|
|
|
|
totalmemory:=0;
|
|
ar:=0;
|
|
getexecutablememoryregionsfromregion(0,$7fffffff,memoryregion);
|
|
for i:=0 to length(memoryregion)-1 do
|
|
begin
|
|
totalmemory:=totalmemory+memoryregion[i].MemorySize;
|
|
if ar<memoryregion[i].MemorySize then ar:=memoryregion[i].MemorySize;
|
|
end;
|
|
|
|
totalread:=0;
|
|
progressbar.Max:=totalmemory;
|
|
progressbar.Position:=0;
|
|
|
|
setlength(buffer,ar);
|
|
|
|
//todo: Replace this with AA scripts
|
|
|
|
|
|
//non inremental
|
|
if not incremental then
|
|
begin
|
|
{
|
|
-------------------------------------------------
|
|
VC++
|
|
-------------------------------------------------
|
|
}
|
|
setlength(vcreplace,6);
|
|
|
|
//mov eax,defaultvalue
|
|
vcreplace[0]:=$b8;
|
|
pdword(@vcreplace[1])^:=defaultreturn;
|
|
//ret
|
|
vcreplace[5]:=$c3;
|
|
|
|
{
|
|
-------------------------------------------------
|
|
DELPHI
|
|
-------------------------------------------------
|
|
}
|
|
|
|
setlength(delphireplace,8);
|
|
//mov edx,counter
|
|
delphireplace[0]:=$ba;
|
|
pdword(@delphireplace[1])^:=defaultreturn;
|
|
|
|
//and eax,edx
|
|
delphireplace[5]:=$21;
|
|
delphireplace[6]:=$d0;
|
|
|
|
//ret
|
|
delphireplace[7]:=$c3;
|
|
|
|
{
|
|
-------------------------------------------------
|
|
IBASIC
|
|
-------------------------------------------------
|
|
}
|
|
|
|
setlength(ibasicreplace,8);
|
|
|
|
//mov eax,defaultvalue
|
|
ibasicreplace[0]:=$b8;
|
|
// pdword(@ibasicreplace[1])^:=dword(defaultreturnf);
|
|
//ret 8
|
|
ibasicreplace[5]:=$c2;
|
|
ibasicreplace[6]:=$08;
|
|
ibasicreplace[7]:=$00;
|
|
|
|
|
|
//mov eax,defaultvaluef
|
|
//ret 8
|
|
|
|
end
|
|
else
|
|
begin
|
|
//allocate 4 bytes to store the current value
|
|
counter:=virtualallocex(processhandle,nil,8,MEM_COMMIT ,PAGE_EXECUTE_READWRITE);
|
|
writeprocessmemory(processhandle,counter,@defaultreturn,4,aw);
|
|
|
|
|
|
{
|
|
-------------------------------------------------
|
|
VC++
|
|
-------------------------------------------------
|
|
}
|
|
setlength(vcreplace,23);
|
|
//mov eax,[counter]
|
|
vcreplace[0]:=$8b;
|
|
vcreplace[1]:=$05;
|
|
pdword(@vcreplace[2])^:=ptrUint(counter);
|
|
|
|
//inc eax
|
|
vcreplace[6]:=$40;
|
|
|
|
//cmp eax,8000
|
|
vcreplace[7]:=$3d;
|
|
pdword(@vcreplace[8])^:=$8000;
|
|
|
|
//jb +2
|
|
vcreplace[12]:=$72;
|
|
vcreplace[13]:=$02;
|
|
|
|
//xor eax,eax
|
|
vcreplace[14]:=$31;
|
|
vcreplace[15]:=$c0;
|
|
|
|
//mov [counter],eax
|
|
vcreplace[16]:=$89;
|
|
vcreplace[17]:=$05;
|
|
pdword(@vcreplace[18])^:=ptrUint(counter);
|
|
|
|
//ret
|
|
vcreplace[22]:=$c3;
|
|
|
|
|
|
{
|
|
-------------------------------------------------
|
|
DELPHI
|
|
-------------------------------------------------
|
|
}
|
|
setlength(delphireplace,23);
|
|
|
|
//push ebx
|
|
delphireplace[0]:=$53;
|
|
|
|
//push edx
|
|
delphireplace[1]:=$52;
|
|
|
|
//xchg ebx,eax
|
|
delphireplace[2]:=$93;
|
|
|
|
|
|
//mov eax,[counter]
|
|
delphireplace[3]:=$8b;
|
|
delphireplace[4]:=$05;
|
|
pdword(@delphireplace[5])^:=ptrUint(counter);
|
|
|
|
|
|
//xor edx,edx
|
|
delphireplace[9]:=$31;
|
|
delphireplace[10]:=$d2;
|
|
|
|
|
|
//div ebx
|
|
delphireplace[11]:=$f7;
|
|
delphireplace[12]:=$fb;
|
|
|
|
//xchg eax,edx
|
|
delphireplace[13]:=$92;
|
|
|
|
//inc [counter]
|
|
delphireplace[14]:=$ff;
|
|
delphireplace[15]:=$05;
|
|
pdword(@delphireplace[16])^:=ptrUint(counter);
|
|
|
|
//pop edx
|
|
delphireplace[20]:=$5a;
|
|
|
|
//pop ebx
|
|
delphireplace[21]:=$5b;
|
|
|
|
|
|
//ret
|
|
delphireplace[22]:=$c3;
|
|
|
|
|
|
{
|
|
-------------------------------------------------
|
|
IBASIC
|
|
-------------------------------------------------
|
|
}
|
|
|
|
|
|
setlength(ibasicreplace,52);
|
|
|
|
//push ebx
|
|
ibasicreplace[0]:=$53;
|
|
|
|
//push edx
|
|
ibasicreplace[1]:=$52;
|
|
|
|
//mov ebx,[esp+4]
|
|
ibasicreplace[2]:=$8b;
|
|
ibasicreplace[3]:=$5c;
|
|
ibasicreplace[4]:=$24;
|
|
ibasicreplace[5]:=$04;
|
|
|
|
|
|
//mov eax,[counter]
|
|
ibasicreplace[6]:=$8b;
|
|
ibasicreplace[7]:=$05;
|
|
pdword(@ibasicreplace[8])^:=ptrUint(counter);
|
|
|
|
|
|
//xor edx,edx
|
|
ibasicreplace[12]:=$31;
|
|
ibasicreplace[13]:=$d2;
|
|
|
|
|
|
//div ebx
|
|
ibasicreplace[14]:=$f7;
|
|
ibasicreplace[15]:=$fb;
|
|
|
|
//xchg eax,edx
|
|
ibasicreplace[16]:=$92;
|
|
|
|
//inc [counter]
|
|
ibasicreplace[17]:=$ff;
|
|
ibasicreplace[18]:=$05;
|
|
pdword(@ibasicreplace[19])^:=ptrUint(counter);
|
|
|
|
//mov [counter+4],eax
|
|
ibasicreplace[23]:=$89;
|
|
ibasicreplace[24]:=$05;
|
|
pdword(@ibasicreplace[25])^:=ptrUint(counter)+4;
|
|
|
|
//fild [counter+4]
|
|
ibasicreplace[29]:=$db;
|
|
ibasicreplace[30]:=$05;
|
|
pdword(@ibasicreplace[31])^:=ptrUint(counter)+4;
|
|
|
|
//fstp [counter+4]
|
|
ibasicreplace[35]:=$d9;
|
|
ibasicreplace[36]:=$1d;
|
|
pdword(@ibasicreplace[37])^:=ptrUint(counter)+4;
|
|
|
|
//mov eax,[counter+4]
|
|
ibasicreplace[41]:=$8b;
|
|
ibasicreplace[42]:=$05;
|
|
pdword(@ibasicreplace[43])^:=ptrUint(counter)+4;
|
|
|
|
//pop edx
|
|
ibasicreplace[47]:=$5a;
|
|
|
|
//pop ebx
|
|
ibasicreplace[48]:=$5b;
|
|
|
|
|
|
//ret 8
|
|
ibasicreplace[49]:=$c2;
|
|
ibasicreplace[50]:=$08;
|
|
ibasicreplace[51]:=$00;
|
|
|
|
end;
|
|
|
|
|
|
msvcrtreplace:=vcreplace; //can use the same code as the vc code
|
|
|
|
|
|
|
|
for i:=0 to length(memoryregion)-1 do
|
|
begin
|
|
|
|
if terminated then break;
|
|
|
|
ar:=0;
|
|
if readprocessmemory(processhandle,pointer(memoryregion[i].baseaddress),@buffer[0],memoryregion[i].MemorySize,ar) then
|
|
begin
|
|
for j:=0 to ar-1 do
|
|
begin
|
|
{
|
|
-------------------------------------------------
|
|
DELPHI
|
|
-------------------------------------------------
|
|
}
|
|
if (j<ar-13) and
|
|
(buffer[j]=$53) and
|
|
(buffer[j+1]=$31) and
|
|
(buffer[j+2]=$db) and
|
|
(buffer[j+3]=$69) and
|
|
(buffer[j+4]=$93) and
|
|
(buffer[j+9]=$05) and
|
|
(buffer[j+10]=$84) and
|
|
(buffer[j+11]=$08) and
|
|
(buffer[j+12]=$08) then
|
|
begin
|
|
//save this code and replace
|
|
save(memoryregion[i].BaseAddress+j,@buffer[j],22);
|
|
l:=length(delphireplace);
|
|
rewritecode(processhandle,memoryregion[i].BaseAddress+j,@delphireplace[0],l);
|
|
end;
|
|
|
|
{
|
|
-------------------------------------------------
|
|
VC++
|
|
-------------------------------------------------
|
|
}
|
|
if (j<ar-39) and
|
|
(buffer[j]=$55) and
|
|
(buffer[j+1]=$8b) and
|
|
(buffer[j+2]=$ec) and
|
|
(buffer[j+3]=$a1) and
|
|
(buffer[j+8]=$69) and
|
|
(buffer[j+9]=$c0) and
|
|
(buffer[j+10]=$fd) and
|
|
(buffer[j+11]=$43) and
|
|
(buffer[j+12]=$03) and
|
|
(buffer[j+13]=$00) and
|
|
(buffer[j+14]=$05) and
|
|
(buffer[j+15]=$c3) and
|
|
(buffer[j+16]=$9e) and
|
|
(buffer[j+17]=$26) and
|
|
(buffer[j+18]=$00) and
|
|
(buffer[j+19]=$a3) and
|
|
(buffer[j+24]=$a1) and
|
|
(buffer[j+29]=$c1) and
|
|
(buffer[j+30]=$f8) and
|
|
(buffer[j+31]=$10) and
|
|
(buffer[j+32]=$25) and
|
|
(buffer[j+33]=$ff) and
|
|
(buffer[j+34]=$7f) and
|
|
(buffer[j+35]=$00) and
|
|
(buffer[j+36]=$00) and
|
|
(buffer[j+37]=$5d) and
|
|
(buffer[j+38]=$c3) then
|
|
begin
|
|
//save this code and replace
|
|
save(memoryregion[i].BaseAddress+j,@buffer[j],26);
|
|
l:=length(vcreplace);
|
|
rewritecode(processhandle,memoryregion[i].BaseAddress+j,@vcreplace[0],l); //size is always 12
|
|
end;
|
|
|
|
{
|
|
-------------------------------------------------
|
|
msvcrt.rand
|
|
-------------------------------------------------
|
|
}
|
|
if (j<ar-34) and
|
|
(buffer[j]=$e8) and
|
|
(buffer[j+5]=$8b) and
|
|
(buffer[j+6]=$48) and
|
|
(buffer[j+8]=$69) and
|
|
(buffer[j+9]=$c9) and
|
|
(buffer[j+10]=$fd) and
|
|
(buffer[j+11]=$43) and
|
|
(buffer[j+12]=$03) and
|
|
(buffer[j+13]=$00) and
|
|
(buffer[j+14]=$81) and
|
|
(buffer[j+15]=$c1) and
|
|
(buffer[j+16]=$c3) and
|
|
(buffer[j+17]=$9e) and
|
|
(buffer[j+18]=$26) and
|
|
(buffer[j+19]=$00) and
|
|
(buffer[j+20]=$89) and
|
|
(buffer[j+21]=$48) and
|
|
(buffer[j+23]=$8b) and
|
|
(buffer[j+24]=$c1) and
|
|
(buffer[j+25]=$c1) and
|
|
(buffer[j+26]=$e8) and
|
|
(buffer[j+27]=$10) and
|
|
(buffer[j+28]=$25) and
|
|
(buffer[j+29]=$ff) and
|
|
(buffer[j+30]=$7f) and
|
|
(buffer[j+31]=$00) and
|
|
(buffer[j+32]=$00) and
|
|
(buffer[j+33]=$c3) then
|
|
begin
|
|
//save this code and replace
|
|
l:=length(msvcrtreplace);
|
|
save(memoryregion[i].BaseAddress+j,@buffer[j],length(msvcrtreplace));
|
|
rewritecode(processhandle,memoryregion[i].BaseAddress+j,@msvcrtreplace[0],l); //size is always 12
|
|
end;
|
|
|
|
|
|
{
|
|
-------------------------------------------------
|
|
ibasic random
|
|
-------------------------------------------------
|
|
}
|
|
if (j<ar-112) and
|
|
(buffer[j]=$55) and
|
|
(buffer[j+1]=$89) and
|
|
(buffer[j+2]=$e5) and
|
|
(buffer[j+3]=$81) and
|
|
(buffer[j+4]=$ec) and
|
|
(buffer[j+5]=$04) and
|
|
(buffer[j+6]=$00) and
|
|
(buffer[j+7]=$00) and
|
|
(buffer[j+8]=$00) and
|
|
(buffer[j+9]=$53) and
|
|
(buffer[j+10]=$57) and
|
|
(buffer[j+11]=$56) and
|
|
(buffer[j+12]=$31) and
|
|
(buffer[j+13]=$c0) and
|
|
(buffer[j+14]=$bb) and
|
|
|
|
(buffer[j+93]=$00) and
|
|
(buffer[j+94]=$00) and
|
|
(buffer[j+95]=$00) and
|
|
(buffer[j+96]=$89) and
|
|
(buffer[j+97]=$c2) and
|
|
(buffer[j+98]=$5e) and
|
|
(buffer[j+99]=$89) and
|
|
(buffer[j+100]=$16) and
|
|
(buffer[j+101]=$b8) and
|
|
|
|
(buffer[j+106]=$50) and
|
|
(buffer[j+107]=$b8) and
|
|
(buffer[j+108]=$c3) and
|
|
(buffer[j+109]=$9e) and
|
|
(buffer[j+110]=$26) and
|
|
(buffer[j+111]=$00) and
|
|
(buffer[j+112]=$bb) and
|
|
(buffer[j+113]=$fd) and
|
|
(buffer[j+114]=$43) and
|
|
(buffer[j+115]=$03) and
|
|
(buffer[j+116]=$00) and
|
|
(buffer[j+117]=$b9) then
|
|
begin
|
|
//save this code and replace
|
|
l:=length(ibasicreplace);
|
|
save(memoryregion[i].BaseAddress+j,@buffer[j],length(ibasicreplace));
|
|
rewritecode(processhandle,memoryregion[i].BaseAddress+j,@ibasicreplace[0],l);
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
inc(totalread,memoryregion[i].MemorySize);
|
|
|
|
try
|
|
progressbar.Position:=totalread;
|
|
except
|
|
terminate;
|
|
end;
|
|
|
|
end;
|
|
|
|
if terminated then synchronize(restore);
|
|
synchronize(done);
|
|
end;
|
|
|
|
|
|
end.
|