Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
��� �: lqcros
� ���:
��� ����ר: ��
����
ܼ : ����
��������δ�������ṩһ�ֿ���ֱ�Ӵ�������ڴһ��exe�ı� �취��
ֻҪ����ʱ��
ܽ exe�������� ƴ�ӵ�һ�����ڴУ��Ϳ���ֱ�Ӵ��ززز
�����������ڴȫ��ȥ
���һ����ʱ�ļ�����ٴʱ�ļ����̡�������δ���Ҳ�ṩ��һ��� �дexe��ǵļ�;����
�����������������Ǽ��� �õ ������رexe�ļ���
Ȼ����������ǰ��������滻�����ڴе�exe��������ݣʽ���к�ִ�еľ������Ŀ������ˡ�
��������л���һЩ��������ĵ 98��������������طл���һ��ʬ����Ŀ���Ӳ���ϣ�
��ʵ�Ǹ�ʬ���������һ������Ŀ�ִ�г���ֱ�����еĻ�ֻ��ʾһ�������ϢȻ����˳��ˣ���
����ַ������ ����صУ���
�����bug���֮������и�õķ����98������
ܽ �رµ�����β�͵Ļ�ϣ��� ͽ̡�
}
{ ******************************************************* }
{ * �����ڴм�������زexe
* }
{ ******************************************************* }
{ * ����
}
{ * buffer: ���ڴе�exe��ַ
}
{ * len: ����ڴexeռ�ó���
}
{ * cmdparam: �����в���(����exe�ļ����ʣ�������в���}
{ * processid: ���صĽ��Id
}
{ * ����ֵ�� ���ɹ�� �̵�handle(processhandle), }
{ ���ʧ��� �Invalid_handle_value }
{ ******************************************************* }
unit peunit;
interface
uses windows;
implementation
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);
type
tvirtualallocex = function (hprocess: thandle; lpaddress: pointer;
dwsize, flallocationtype: dword; flprotect:
dword): pointer; stdcall;
var
myvirtualallocex: tvirtualallocex = nil;
{ �����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 �صļ�� �ַ
���dz�������ʱռ�õ���ڴ
begin
sz := imagesize - peh.optionalheader.sizeofimage;
inc(peh.optionalheader.sizeofimage, sz); // ������ռ������ڴ
inc(pesech[peh.fileheader.numberofsections-1].misc.virtualsize, sz); //
�������һ��ռ������ڴ
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;
{ ������ǽ��ռ�е��} �ڴ
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;
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
��������»»»
interface
{$imagebase $10000000}
uses
windows;
type
tsections = array [0..0] of timagesectionheader;
implementation
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.