|
[x]
Posted via EE Mobile
|
||
Search, ask, and monitor your questions on the go with EE Mobile. Visit Experts Exchange from your mobile device and never be out of touch again. |
||
| Question |
|
[x]
Attachment Details
|
||
|
[x]
The Solution Rating System
|
||
With so many solutions, how can you tell which solutions are most likely to help you and which ones are not? To provide you with a tool to use, we rate our solutions based on various elements that most accurately determine if a solution is a quality solution. To explain what factors affect the solution rating, here are the elements we take into consideration when formulating our solution rating.
Your Input Matters If you have any suggestions that you would like to make for our rating system, please ask a question in the Suggestions Zone of Community Support. Thank you! |
||
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: |
unit MemoryModule;
interface
uses
SysUtils,
Windows;
type
HMemoryModule = Pointer;
PMemoryModule = ^TMemoryModule;
TMemoryModule = record
Headers: PImageNtHeaders;
CodeBase: Pointer;
Modules: Pointer;
NumModules,
Initialized: Integer;
end;
TDLLEntryProc = function(hInstDLL, Reason: DWORD; lpReserved: Pointer): BOOL; stdcall;
PImageBaseRelocation = ^TImageBaseRelocation;
TImageBaseRelocation = packed record
VirtualAddress,
SizeOfBlock: DWORD;
end;
PImageImportDescriptor = ^TImageImportDescriptor;
TImageImportDescriptor = packed record
Case Integer Of
0:(Characteristics: DWORD);
1:(OriginalFirstThunk: DWORD; TimeDateStamp: DWORD; ForwarderChain: DWORD; Name: DWORD; FirstThunk: DWORD);
end;
PImageImportByName = ^TImageImportByName;
TImageImportByName = packed record
Hint: WORD;
Name: Array[0..255] Of Byte;
end;
const
IMAGE_DIRECTORY_ENTRY_BASERELOC = 5;
IMAGE_REL_BASED_HIGHLOW = 3;
IMAGE_ORDINAL_FLAG = $80000000;
IMAGE_SIZEOF_BASE_RELOCATION = SizeOf(TImageBaseRelocation);
ProtectionFlags : Array[Boolean,Boolean,Boolean] Of Integer =
(((PAGE_NOACCESS,PAGE_WRITECOPY),
(PAGE_READONLY,PAGE_READWRITE)),
((PAGE_EXECUTE,PAGE_EXECUTE_WRITECOPY),
(PAGE_EXECUTE_READ,PAGE_EXECUTE_READWRITE)));
{--------------------------------------------------------------------------------------}
function MemoryLoadLibrary(Data: Pointer): HMemoryModule;
function MemoryGetProcAddress(MemoryModule: HMemoryModule; Name: PAnsiChar): Pointer;
procedure MemoryFreeLibrary(MemoryModule: HMemoryModule);
{--------------------------------------------------------------------------------------}
implementation
function GetHeaderDictionary(MemoryModule: PMemoryModule; IDX: Integer): TImageDataDirectory;
begin
Result := MemoryModule^.Headers^.OptionalHeader.DataDirectory[IDX];
end;
function CalculateAddress(Base: Pointer; Offset: DWORD): Pointer;
begin
Result := Pointer(DWORD(Base) + Offset);
end;
function FieldOffset(const Struc; const Field): DWORD;
begin
Result := DWORD(@Field) - DWORD(@Struc);
end;
function ImageFirstSection(NtHeader: PImageNtHeaders): PImageSectionHeader;
begin
Result := PImageSectionHeader(DWORD(NtHeader) + FieldOffset(NtHeader^, NtHeader^.OptionalHeader) + NtHeader^.FileHeader.SizeOfOptionalHeader);
end;
function ImageSnapByOrdinal(Ordinal: DWORD): Boolean;
begin
Result := (Ordinal And IMAGE_ORDINAL_FLAG) <> 0;
end;
function ImageOrdinal(Ordinal: DWORD): DWORD;
begin
Result := Ordinal And $FFFF;
end;
procedure CopySections(Data: Pointer; OldHeaders: PImageNtHeaders; MemoryModule: PMemoryModule);
var
I : Integer;
Size : DWORD;
CodeBase,
Dest : Pointer;
Section : PImageSectionHeader;
begin
CodeBase := MemoryModule^.CodeBase;
Section := ImageFirstSection(MemoryModule^.Headers);
For I := 0 To MemoryModule^.Headers^.FileHeader.NumberOfSections - 1 Do
begin
If Section^.SizeOfRawData = 0 Then
begin
Size := OldHeaders^.OptionalHeader.SectionAlignment;
If Size > 0 Then
begin
Dest := VirtualAlloc(CalculateAddress(CodeBase,Section^.VirtualAddress),Size,MEM_COMMIT,PAGE_READWRITE);
Section^.Misc.PhysicalAddress := DWORD(Dest);
FillChar(Dest^,Size,0);
end;
Inc(Section);
Continue;
end;
Dest := VirtualAlloc(CalculateAddress(CodeBase,Section^.VirtualAddress),Section^.SizeOfRawData,MEM_COMMIT,PAGE_READWRITE);
Windows.CopyMemory(Dest,CalculateAddress(Data,Section^.PointerToRawData),Section^.SizeOfRawData);
Section^.Misc.PhysicalAddress := DWORD(Dest);
Inc(Section);
end;
end;
procedure FinalizeSections(MemoryModule: PMemoryModule);
var
I : Integer;
Section : PImageSectionHeader;
Executable,
Readable,
Writeable : Boolean;
Protect,
OldProtect,
Size : DWORD;
begin
Section := ImageFirstSection(MemoryModule^.Headers);
For I := 0 To MemoryModule^.Headers^.FileHeader.NumberOfSections - 1 Do
begin
Executable := (Section^.Characteristics And IMAGE_SCN_MEM_EXECUTE) <> 0;
Readable := (Section^.Characteristics And IMAGE_SCN_MEM_READ) <> 0;
Writeable := (Section^.Characteristics And IMAGE_SCN_MEM_WRITE) <> 0;
If (Section^.Characteristics And IMAGE_SCN_MEM_DISCARDABLE) <> 0 Then
begin
VirtualFree(Pointer(Section^.Misc.PhysicalAddress),Section^.SizeOfRawData,MEM_DECOMMIT);
Inc(Section);
Continue;
end;
Protect := ProtectionFlags[Executable][Readable][Writeable];
If (Section^.Characteristics And IMAGE_SCN_MEM_NOT_CACHED) <> 0 Then
begin
Protect := Protect Or PAGE_NOCACHE;
end;
Size := Section^.SizeOfRawData;
If Size = 0 Then
begin
If (Section^.Characteristics And IMAGE_SCN_CNT_INITIALIZED_DATA) <> 0 Then
begin
Size := MemoryModule^.Headers^.OptionalHeader.SizeOfInitializedData;
end
Else If (Section^.Characteristics And IMAGE_SCN_CNT_UNINITIALIZED_DATA) <> 0 Then
begin
Size := MemoryModule^.Headers.OptionalHeader.SizeOfUninitializedData;
end;
end;
If Size > 0 Then
begin
VirtualProtect(Pointer(Section^.Misc.PhysicalAddress),Section^.SizeOfRawData,Protect,OldProtect);
end;
Inc(Section);
end;
end;
procedure PerformBaseRelocation(MemoryModule: PMemoryModule; Delta: DWORD);
var
I : DWORD;
CodeBase : Pointer;
Directory : TImageDataDirectory;
Relocation : PImageBaseRelocation;
Dest,
RelInfo,
PatchAddrHL : Pointer;
iType,
Offset : Integer;
begin
CodeBase := MemoryModule^.CodeBase;
Directory := GetHeaderDictionary(MemoryModule,IMAGE_DIRECTORY_ENTRY_BASERELOC);
If Directory.Size > 0 Then
begin
Relocation := PImageBaseRelocation(CalculateAddress(CodeBase,Directory.VirtualAddress));
While Relocation^.VirtualAddress > 0 Do
begin
Dest := CalculateAddress(CodeBase,Relocation^.VirtualAddress);
RelInfo := Pointer(DWORD(@Relocation) + IMAGE_SIZEOF_BASE_RELOCATION);
For I := 0 To ((Relocation^.SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) div 2) - 1 Do
begin
iType := PWORD(RelInfo)^ SHR 12;
Offset := PWORD(RelInfo)^ And $0FFF;
Case iType Of
//IMAGE_REL_BASED_ABSOLUTE:
IMAGE_REL_BASED_HIGHLOW:
begin
PatchAddrHL := CalculateAddress(Dest,Offset);
Inc(PByte(PatchAddrHL),Delta);
end;
end;
Inc(PWORD(RelInfo));
end;
Relocation := PImageBaseRelocation(CalculateAddress(Relocation,Relocation^.SizeOfBlock));
end;
end;
end;
function BuildImportTable(MemoryModule: PMemoryModule): Integer;
var
CodeBase : Pointer;
Directory : TImageDataDirectory;
ImportDesc : PImageImportDescriptor;
ThunkRef,
FuncRef : Pointer;
Handle : DWORD;
ThunkData : PImageImportByName;
LibraryName : AnsiString;
begin
Result := 1;
CodeBase := MemoryModule^.CodeBase;
Directory := GetHeaderDictionary(MemoryModule,IMAGE_DIRECTORY_ENTRY_IMPORT);
If Directory.Size > 0 Then
begin
ImportDesc := PImageImportDescriptor(CalculateAddress(CodeBase,Directory.VirtualAddress));
While (Not(IsBadReadPtr(ImportDesc,SizeOf(TImageImportDescriptor)))) And (ImportDesc^.Name > 0) Do
begin
LibraryName := PAnsiChar(CalculateAddress(CodeBase,ImportDesc^.Name));
Handle := LoadLibraryA(PAnsiChar(LibraryName));
If Handle < HINSTANCE_ERROR Then
begin
MessageBox(0,PChar(SysErrorMessage(GetLastError)),'',0);
Result := 0;
Break;
end;
ReAllocMem(MemoryModule^.Modules,(MemoryModule^.NumModules + 1) * SizeOf(DWORD));
If MemoryModule^.Modules = nil Then
begin
Result := 0;
Break;
end;
PDWORD(@PByte(MemoryModule^.Modules)[(MemoryModule^.NumModules + 1) * SizeOf(DWORD)])^ := Handle;
If ImportDesc^.OriginalFirstThunk <> 0 Then
begin
ThunkRef := CalculateAddress(CodeBase,ImportDesc^.OriginalFirstThunk);
FuncRef := CalculateAddress(CodeBase,ImportDesc^.FirstThunk);
end
Else
begin
ThunkRef := CalculateAddress(CodeBase,ImportDesc^.FirstThunk);
FuncRef := CalculateAddress(CodeBase,ImportDesc^.FirstThunk);
end;
While PDWORD(ThunkRef)^ > 0 Do
begin
If ImageSnapByOrdinal(PDWORD(ThunkRef)^) Then
begin
PDWORD(FuncRef)^ := DWORD(GetProcAddress(Handle,PAnsiChar(Pointer(ImageOrdinal(PDWORD(ThunkRef)^)))));
end
Else
begin
ThunkData := PImageImportByName(CalculateAddress(CodeBase,PDWORD(ThunkRef)^));
PDWORD(FuncRef)^ := DWORD(GetProcAddress(Handle,PAnsiChar(@ThunkData^.Name)));
end;
If PDWORD(FuncRef)^ = 0 Then
begin
Result := 0;
Break;
end;
Inc(PDWORD(ThunkRef));
Inc(PDWORD(FuncRef));
end;
If Result = 0 Then Break;
Inc(ImportDesc);
end;
end;
end;
function MemoryLoadLibrary(Data: Pointer): HMemoryModule;
var
pResult : PMemoryModule;
DosHeader : PImageDosHeader;
OldHeader : PImageNtHeaders;
Code,
Headers : Pointer;
LocationDelta : DWORD;
DLLEntry : TDLLEntryProc;
Successful : Boolean;
begin
Result := nil;
DosHeader := PImageDosHeader(Data);
If DosHeader^.e_magic <> IMAGE_DOS_SIGNATURE Then Exit;
OldHeader := PImageNtHeaders(@PByte(Data)[DosHeader^._lfanew]);
If OldHeader^.Signature <> IMAGE_NT_SIGNATURE Then Exit;
Code := VirtualAlloc(Pointer(OldHeader^.OptionalHeader.ImageBase),OldHeader.OptionalHeader.SizeOfImage,MEM_RESERVE,PAGE_READWRITE);
If Code = nil Then
begin
Code := VirtualAlloc(nil,OldHeader^.OptionalHeader.SizeOfImage,MEM_RESERVE,PAGE_READWRITE);
If Code = nil Then Exit;
end;
pResult := PMemoryModule(HeapAlloc(GetProcessHeap,0,SizeOf(TMemoryModule)));
pResult^.CodeBase := Code;
pResult^.NumModules := 0;
pResult^.Modules := nil;
pResult^.Initialized := 0;
VirtualAlloc(Code,OldHeader^.OptionalHeader.SizeOfImage,MEM_COMMIT,PAGE_READWRITE);
Headers := VirtualAlloc(Code,OldHeader^.OptionalHeader.SizeOfHeaders,MEM_COMMIT,PAGE_READWRITE);
{$WARNINGS OFF}
Move(DosHeader^,Headers^,DosHeader^._lfanew + OldHeader^.OptionalHeader.SizeOfHeaders);
{$WARNINGS ON}
pResult^.Headers := PImageNtHeaders(@PByte(Headers)[DosHeader^._lfanew]);
pResult^.Headers^.OptionalHeader.ImageBase := DWORD(Code);
CopySections(Data,OldHeader,pResult);
LocationDelta := DWORD(PByte(Code) - OldHeader^.OptionalHeader.ImageBase);
If LocationDelta <> 0 Then
begin
PerformBaseRelocation(pResult,LocationDelta);
end;
Try
If Not(BuildImportTable(pResult) <> 0) Then Exit;
FinalizeSections(pResult);
If pResult^.Headers^.OptionalHeader.AddressOfEntryPoint <> 0 Then
begin
DLLEntry := TDLLEntryProc(CalculateAddress(Code,pResult^.Headers^.OptionalHeader.AddressOfEntryPoint));
If @DLLEntry = nil Then Exit;
Successful := DLLEntry(DWORD(Code),DLL_PROCESS_ATTACH,nil);
If Not(Successful) Then Exit;
pResult^.Initialized := 1;
end;
Result := HMemoryModule(pResult);
Except
MemoryFreeLibrary(pResult);
end;
end;
function MemoryGetProcAddress(MemoryModule: HMemoryModule; Name: PAnsiChar): Pointer;
var
CodeBase : Pointer;
IDX : Integer;
I : DWORD;
NameRef : Pointer;
Ordinal : Pointer;
pExports : PImageExportDirectory;
Directory : TImageDataDirectory;
begin
Result := nil;
CodeBase := PMemoryModule(MemoryModule)^.CodeBase;
IDX := -1;
Directory := GetHeaderDictionary(PMemoryModule(MemoryModule),IMAGE_DIRECTORY_ENTRY_EXPORT);
If Directory.Size = 0 Then Exit;
pExports := PImageExportDirectory(CalculateAddress(CodeBase,Directory.VirtualAddress));
If (pExports^.NumberOfNames = 0) Or (pExports^.NumberOfFunctions = 0) Then Exit;
NameRef := CalculateAddress(CodeBase,DWORD(pExports^.AddressOfNames));
Ordinal := CalculateAddress(CodeBase,DWORD(pExports^.AddressOfNameOrdinals));
For I := 0 To pExports^.NumberOfNames - 1 Do
begin
If CompareStringA(LOCALE_USER_DEFAULT,0,Name,-1,PAnsiChar(CalculateAddress(CodeBase,PDWORD(NameRef)^)),-1) <> -2 Then
begin
IDX := PWORD(Ordinal)^;
Break;
end;
Inc(PDWORD(NameRef));
Inc(PWORD(Ordinal));
end;
If IDX = -1 Then Exit;
If DWORD(IDX) > pExports^.NumberOfFunctions Then Exit;
{$WARNINGS OFF}
Result := CalculateAddress(CodeBase,PDWORD(CalculateAddress(CodeBase,DWORD(pExports^.AddressOfFunctions) + (IDX * SizeOf(DWORD))))^);
{$WARNINGS ON}
end;
procedure MemoryFreeLibrary(MemoryModule: HMemoryModule);
var
I : Integer;
Module : PMemoryModule;
DLLEntry : TDLLEntryProc;
begin
Module := PMemoryModule(MemoryModule);
If Module <> nil Then
begin
If Module^.Initialized <> 0 Then
begin
DLLEntry := TDLLEntryProc(CalculateAddress(Module^.CodeBase,Module^.Headers^.OptionalHeader.AddressOfEntryPoint));
DllEntry(DWORD(Module^.CodeBase),DLL_PROCESS_DETACH,nil);
Module^.Initialized := 0;
end;
If Module^.Modules <> nil Then
begin
For I := 0 To Module^.NumModules - 1 Do
begin
If PDWORD(@PByte(Module^.Modules)[(I + 1) * SizeOf(DWORD)])^ <> INVALID_HANDLE_VALUE Then
begin
FreeLibrary(PDWORD(@PByte(Module^.Modules)[(I + 1) * SizeOf(DWORD)])^);
end;
end;
Freemem(Module^.Modules);
end;
If Module^.CodeBase <> nil Then
begin
VirtualFree(Module^.CodeBase,0,MEM_RELEASE);
end;
HeapFree(GetProcessHeap,0,Module);
end;
end;
end.
|
Advertisement
| Hall of Fame |