BanMe Master Cheater
Reputation: 0
Joined: 29 Nov 2005 Posts: 375 Location: Farmington NH, USA
|
Posted: Tue Oct 07, 2008 5:10 pm Post subject: Linked List Hooking engine...also implementing WLSI... |
|
|
reworked all the Class code into namespace hkHook to avoid the use of new and delete(the CRT equivelents of malloc) i decided to go with a local heap, removed all vestiges of the CRT.. hate that damn thing, small updates to the exported functions though i think im gonna have to use a def file so the compiler doesnt mangle them ... but this is a nice step in the write direction..
here my code so far.. questions and comments are welcome..
[file affectionate.cpp]
| Code: |
#pragma once
#define _CRT_SECURE_NO_DEPRECATE
#include "hkHook.h"
using namespace hkHook;
//SIG^2 Code here minor mods ;]
//*******************************************************************************************************
// Fills the various structures with info of a PE image. The PE image is located at modulePos.
//
//*******************************************************************************************************
bool UsrReadPEInfo(char *modulePos, MZHeader *outMZ, PE_Header *outPE, PE_ExtHeader *outpeXH,SectionHeader **outSecHdr)
{
// read MZ Header
MZHeader *mzH;
mzH = (MZHeader *)modulePos;
if(mzH->signature != 0x5a4d) // MZ
{
//printf("File does not have MZ header\n");
return false;
}
// read PE Header
PE_Header *peH;
peH = (PE_Header *)(modulePos + mzH->offsetToPE);
if(peH->sizeOfOptionHeader != sizeof(PE_ExtHeader))
{
//printf("Unexpected option header size.\n");
return false;
}
// read PE Ext Header
PE_ExtHeader *peXH;
peXH = (PE_ExtHeader *)((char *)peH + sizeof(PE_Header));
// read the sections
SectionHeader *secHdr = (SectionHeader *)((char *)peXH + sizeof(PE_ExtHeader));
*outMZ = *mzH;
*outPE = *peH;
*outpeXH = *peXH;
*outSecHdr = secHdr;
return true;
}
//*******************************************************************************************************
// Returns the total size required to load a PE image into memory
//
//*******************************************************************************************************
int UsrCalcImageSize(MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH,
SectionHeader *inSecHdr)
{
int result = 0;
int alignment = inpeXH->sectionAlignment;
if(inpeXH->sizeOfHeaders % alignment == 0)
result += inpeXH->sizeOfHeaders;
else
{
int val = inpeXH->sizeOfHeaders / alignment;
val++;
result += (val * alignment);
}
for(int i = 0; i < inPE->numSections; i++)
{
if(inSecHdr[i].virtualSize)
{
if(inSecHdr[i].virtualSize % alignment == 0)
result += inSecHdr[i].virtualSize;
else
{
int val = inSecHdr[i].virtualSize / alignment;
val++;
result += (val * alignment);
}
}
}
return result;
}
//*******************************************************************************************************
// Returns the aligned size of a section
//
//*******************************************************************************************************
unsigned long UsrGetAlignedSize(unsigned long curSize, unsigned long alignment)
{
if(curSize % alignment == 0)
return curSize;
else
{
int val = curSize / alignment;
val++;
return (val * alignment);
}
}
//*******************************************************************************************************
// Copy a PE image from exePtr to ptrLoc with proper memory alignment of all sections
//
//*******************************************************************************************************
bool UsrLoadFile(char *exePtr, MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH,
SectionHeader *inSecHdr, LPVOID ptrLoc)
{
char *outPtr = (char *)ptrLoc;
memcpy(outPtr, exePtr, inpeXH->sizeOfHeaders);
outPtr += UsrGetAlignedSize(inpeXH->sizeOfHeaders, inpeXH->sectionAlignment);
for(int i = 0; i < inPE->numSections; i++)
{
if(inSecHdr[i].sizeOfRawData > 0)
{
unsigned long toRead = inSecHdr[i].sizeOfRawData;
if(toRead > inSecHdr[i].virtualSize)
toRead = inSecHdr[i].virtualSize;
memcpy(outPtr, exePtr + inSecHdr[i].pointerToRawData, toRead);
outPtr += UsrGetAlignedSize(inSecHdr[i].virtualSize, inpeXH->sectionAlignment);
}
}
return true;
}
//*******************************************************************************************************
// Loads the file into Shared memory and aligns it xD
//
//*******************************************************************************************************
LPVOID UsrShareFile(char *DllPathName)
{
char moduleFilename[MAX_PATH + 1];
LPVOID ptrLoc = NULL;
MZHeader mzH2;
PE_Header peH2;
PE_ExtHeader peXH2;
SectionHeader *secHdr2;
if( myStrlenA(DllPathName) >= MAX_PATH )
{
return NULL;
}
strcpy(moduleFilename, DllPathName);
// load this EXE into memory because we need its original Import Hint Table
HANDLE fp;
MEMORY_BASIC_INFORMATION MBI;
fp = CreateFile( moduleFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if( fp != INVALID_HANDLE_VALUE )
{
HANDLE fmo = OpenFileMapping( SECTION_ALL_ACCESS,false,"MEXACUTE" );
VirtualQuery( fmo, &MBI, sizeof(MEMORY_BASIC_INFORMATION));
BY_HANDLE_FILE_INFORMATION fileInfo;
BY_HANDLE_FILE_INFORMATION pagefileinfo;
GetFileInformationByHandle(fp, &fileInfo);
GetFileInformationByHandle(fmo, &pagefileinfo);
DWORD pagefileSize = pagefileinfo.nFileSizeLow;
DWORD fileSize = fileInfo.nFileSizeLow;
//printf("Size = %d\n", fileSize);
if(fileSize)
{
LPVOID exePtr = HeapAlloc(GetProcessHeap(), 0, fileSize);
if(exePtr)
{
DWORD read;
if(ReadFile(fp, exePtr, fileSize, &read, NULL) && read == fileSize)
{
if(!UsrReadPEInfo((char *)exePtr, &mzH2, &peH2, &peXH2, &secHdr2))
{
return NULL;
}
int imageSize = UsrCalcImageSize(&mzH2, &peH2, &peXH2, secHdr2);
//ptrLoc = VirtualAlloc(NULL, imageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
ptrLoc = fmo;
if(ptrLoc)
{
if(!UsrLoadFile((char *)exePtr, &mzH2, &peH2, &peXH2, secHdr2, ptrLoc))
{
return NULL;
}
}
}
HeapFree(GetProcessHeap(), 0, exePtr);
}
}
CloseHandle(fp);
}
return ptrLoc;
}
DWORD UsrGetExportAddr(HMODULE hModule, char *apiName)
{
if(!hModule || !apiName)
return 0;
char *ptr = (char *)hModule;
ptr += 0x3c; // offset 0x3c contains offset to PE header
ptr = (char *)(*(DWORD *)ptr) + (DWORD)hModule + 0x78; // offset 78h into PE header contains addr of export table
ptr = (char *)(*(DWORD *)ptr) + (DWORD)hModule; // ptr now points to export directory table
// offset 24 into the export directory table == number of entries in the Export Name Pointer Table
// table
DWORD numEntries = *(DWORD *)(ptr + 24);
//printf("NumEntries = %d\n", numEntries);
DWORD *ExportNamePointerTable = (DWORD *)(*(DWORD *)(ptr + 32) + hModule); // offset 32 into export directory contains offset to Export Name Pointer Table
DWORD ordinalBase = *((DWORD *)(ptr + 16));
//printf("OrdinalBase is %d\n", ordinalBase);
WORD *ExportOrdinalTable = (WORD *)((*(DWORD *)(ptr + 36)) + hModule); // offset 36 into export directory contains offset to Ordinal Table
DWORD *ExportAddrTable = (DWORD *)((*(DWORD *)(ptr + 28)) + hModule); // offset 28 into export directory contains offset to Export Addr Table
for(DWORD i = 0; i < numEntries; i++)
{
char *exportName = (char *)(ExportNamePointerTable[i] + hModule);
if(myStrcmpA(exportName, apiName) == TRUE)
{
WORD ordinal = ExportOrdinalTable[i];
//printf("%s (i = %d) Ordinal = %d at %X\n", exportName, i, ordinal, ExportAddrTable[ordinal]);
return (DWORD)(ExportAddrTable[ordinal]);
}
}
return 0;
}
//returns null on failure and positive integer relating to the API Sought
DWORD UsrGetProcAddr(LPCSTR ModName, char *apiname)
{
DWORD pfn = NULL;
HMODULE hMod;
hMod = GetModuleHandle(ModName);
if(hMod == INVALID_HANDLE_VALUE)
{
return pfn;
}
pfn = UsrGetExportAddr(hMod,apiname);
if(pfn == NULL)
{
return pfn;
}
return pfn;
}
/*-----------Uses hotpatching by sak254 modded by me --------*/
//DWORD index = UsrGetExportAddr(GetModuleHandle("ntdll.dll"),"NtMapViewOfSection")+1;
bool VirtualProtectHookCheck = 0;
bool UsrHotPatchAddr(void *oldProc, void *newProc, void**ppOrigFn)
{
bool bRet = false;
DWORD oldProtect = NULL;
WORD* pJumpBack = (WORD*)oldProc;
BYTE* pLongJump = ((BYTE*)oldProc-5);
DWORD* pLongJumpAdr = ((DWORD*)oldProc-1);
DWORD pfnVirtualProtect = UsrGetProcAddr("Kernel32.dll", "VirtualProtect");
WORD* pByteCheck = (WORD*)pfnVirtualProtect;
if(0xff8b == *pByteCheck)
{
VirtualProtect(pLongJump, 7, PAGE_EXECUTE_WRITECOPY, &oldProtect);
}
else
{
__asm
{
push [oldProtect]
push PAGE_EXECUTE_WRITECOPY
push 7
push pLongJump
mov edi,edi
push ebp
mov [ebp],esp
jmp pfnVirtualProtect+5
}
VirtualProtectHookCheck = 1;
}
// don’t hook functions which have already been hooked
if ((0xff8b == *pJumpBack) &&
(0x90 == *pLongJump) &&
(0x90909090 == *pLongJumpAdr))
{
*pLongJump = 0xE9; // long jmp
*pLongJumpAdr = ((DWORD)newProc)-((DWORD)oldProc); //
*pJumpBack = 0xF9EB; // short jump back -7 (back 5, plus two for this jump)
if (ppOrigFn)
*ppOrigFn = ((BYTE*)oldProc)+2;
bRet = true;
}
if(VirtualProtectHookCheck == 0)
{
VirtualProtect(pLongJump, 7, oldProtect, &oldProtect);
}
else
{
__asm
{
push [oldProtect]
push oldProtect
push 7
push pLongJump
mov edi,edi
push ebp
mov [ebp],esp
jmp pfnVirtualProtect+5
}
}
return bRet;
}
bool UsrHotUnpatch(void*oldProc) // the original fn ptr, not "ppOrigFn" from HotPatch
{
bool bRet = false;
DWORD oldProtect = NULL;
WORD* pJumpBack = (WORD*)oldProc;
if(VirtualProtectHookCheck==0)
{
VirtualProtect(pJumpBack, 2, PAGE_EXECUTE_WRITECOPY, &oldProtect);
}
else
{
_asm
{
push [oldProtect]
push PAGE_EXECUTE_WRITECOPY
push 2
push pJumpBack
mov edi,edi
push ebp
mov [ebp],esp
jmp VirtualProtect+5
}
}
if (0xF9EB == *pJumpBack)
{
*pJumpBack = 0xff8b; // mov edi, edi = nop
bRet = true;
}
VirtualProtect(pJumpBack, 2, oldProtect, &oldProtect);
return bRet;
}
DWORD UsrGetRemoteProcAddr(DWORD process_identifier,char* module_name,char* procedure_name)
{
HANDLE handle_snapshot_module;
MODULEENTRY32 module_entry;
IMAGE_DOS_HEADER dos_header;
IMAGE_NT_HEADERS nt_header;
IMAGE_EXPORT_DIRECTORY export_directory;
int rpm_result;
DWORD bytes_read;
DWORD counter;
WORD function_ordinal = 0;
DWORD address_of_names;
DWORD function_address = 0;
char function_name[MAX_PATH];
bool function_found = false;
if(process_identifier==0||module_name==0||procedure_name==0)
{
return 0;
}
handle_snapshot_module = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,process_identifier);
if(handle_snapshot_module==INVALID_HANDLE_VALUE)
{
return 0;
}
module_entry.dwSize = sizeof(module_entry);
if(Module32First(handle_snapshot_module,&module_entry)==0)
{
goto END_FAIL;
}
do
{
if(lstrcmpi(module_name,module_entry.szModule)==0)
{
rpm_result = Toolhelp32ReadProcessMemory
(
process_identifier,
(void*)module_entry.modBaseAddr,
&dos_header,
sizeof(dos_header),
&bytes_read
);
if(rpm_result==0||bytes_read!=sizeof(dos_header))
{
goto END_FAIL;
}
rpm_result = Toolhelp32ReadProcessMemory
(
process_identifier,
(void*)(module_entry.modBaseAddr+dos_header.e_lfanew),
&nt_header,
sizeof(nt_header),
&bytes_read
);
if(rpm_result==0||bytes_read!=sizeof(nt_header))
{
goto END_FAIL;
}
rpm_result = Toolhelp32ReadProcessMemory
(
process_identifier,
(void*)(module_entry.modBaseAddr+nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress),
&export_directory,
sizeof(export_directory),
&bytes_read
);
if(rpm_result==0||bytes_read!=sizeof(export_directory))
{
goto END_FAIL;
}
if(procedure_name<=(const char*)0x0000FFFF)
{
for(counter = 0;counter<export_directory.NumberOfFunctions;counter++)
{
rpm_result = Toolhelp32ReadProcessMemory
(
process_identifier,
(void*)(module_entry.modBaseAddr+export_directory.AddressOfNameOrdinals+counter*2),
&function_ordinal,
sizeof(function_ordinal),
&bytes_read
);
if(rpm_result==0||bytes_read!=sizeof(function_ordinal))
{
goto END_FAIL;
}
if(LOWORD((DWORD)procedure_name)==function_ordinal+1)
{
function_found = true;
break;
}
}
}
else
{
for(counter = 0;counter<export_directory.NumberOfNames;counter++)
{
rpm_result = Toolhelp32ReadProcessMemory
(
process_identifier,
(void*)(module_entry.modBaseAddr+export_directory.AddressOfNames+counter*4),
&address_of_names,
sizeof(address_of_names),
&bytes_read
);
if(rpm_result==0||bytes_read!=sizeof(address_of_names))
{
goto END_FAIL;
}
rpm_result = Toolhelp32ReadProcessMemory
(
process_identifier,
(void*)(module_entry.modBaseAddr+address_of_names),
&function_name,
sizeof(function_name),
&bytes_read
);
if(rpm_result==0||bytes_read!=sizeof(function_name))
{
goto END_FAIL;
}
if(lstrcmpi(procedure_name,function_name)==0)
{
rpm_result = Toolhelp32ReadProcessMemory
(
process_identifier,
(void*)(module_entry.modBaseAddr+export_directory.AddressOfNameOrdinals+counter*2),
&function_ordinal,
sizeof(function_ordinal),
&bytes_read
);
if(rpm_result==0||bytes_read!=sizeof(function_ordinal))
{
goto END_FAIL;
}
function_found = true;
break;
}
}
}
if(function_found)
{
rpm_result = Toolhelp32ReadProcessMemory
(
process_identifier,
(void*)(module_entry.modBaseAddr+export_directory.AddressOfFunctions+function_ordinal*4),
&function_address,
sizeof(function_address),
&bytes_read
);
if(rpm_result==0||bytes_read!=sizeof(function_address))
{
goto END_FAIL;
}
function_address += (DWORD)module_entry.modBaseAddr;
}
break;
}
}
while(Module32Next(handle_snapshot_module,&module_entry)!=0);
END_FAIL:
CloseHandle(handle_snapshot_module);
return function_address;
}
PcLLHook UsrHkInit(char* ProcessName)
{
if(!hkHook::hkInitSection())
{
return false;
}
hkHook::hkSetTargetExeName(ProcessName);
PcLLHook InitialEntry = hkHook::hkAddEntryForHook();
if(InitialEntry == 0)
{
return 0;
}
return InitialEntry;
}
PcLLHook UsrSetHkParams(DWORD tAddr,DWORD HkAddr,DWORD HkSz,cLLHook *HkStruct)
{
cLLHook *cHk;
cHk = HkStruct;
cHk->bJmp = 0xE8;
cHk->hkTAddress = tAddr;
cHk->hkAddress = HkAddr;
cHk->TProcessId = GetProcessId(UsrDrOpenProcess(hkHook::cProcessName));
cHk->NextHook = hkHook::hkAddEntryForHook();
return cHk;
}
bool UsrInstallHook(PcLLHook HkParams)
{
DWORD nbw;
DWORD oProt;
LPVOID HkMem;
if(!VirtualProtectEx(UsrDrOpenProcess(cProcessName),(LPVOID)HkParams->hkTAddress,HkParams->hkSz,PAGE_EXECUTE_READWRITE,&oProt))
{
return false;
}
if(!WriteProcessMemory(UsrDrOpenProcess(cProcessName),(LPVOID)(HkParams->hkTAddress),(LPCVOID)HkParams->bJmp,sizeof(unsigned char),&nbw))
{
return false;
}
if(!WriteProcessMemory(UsrDrOpenProcess(cProcessName),(LPVOID)HkParams->hkTAddress+4,(LPCVOID)HkParams->hkAddress,sizeof(DWORD),&nbw))
{
return false;
}
HkMem = VirtualAllocEx(UsrDrOpenProcess(cProcessName),NULL,(SIZE_T)HkParams->hkSz,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if(!WriteProcessMemory(UsrDrOpenProcess(cProcessName),HkMem,&HkParams->hkAddress,HkParams->hkSz,&nbw))
{
return false;
}
HkParams->Installed = 1;
return true;
}
// UsrDrOpenProcess Opens a Process Directly by its ExeFileName
// Standard shit here... ;)
HANDLE UsrDrOpenProcess(char *ProcN)
{
HANDLE hLocal = INVALID_HANDLE_VALUE;
int tS = 0;
BOOL tB = false;
HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS,0 );
PROCESSENTRY32 PE;
PE.dwSize = sizeof( PROCESSENTRY32 );
tB = Process32First( hSnapShot,&PE );
if(!tB)
{
return INVALID_HANDLE_VALUE;
}
while( Process32Next( hSnapShot,&PE ) != false)
{
tS = strcmp( ProcN,PE.szExeFile );
if(tS == 0)
{
hLocal = OpenProcess( PROCESS_ALL_ACCESS,false,PE.th32ProcessID );
CloseHandle(hSnapShot);
return hLocal;
}
}
CloseHandle(hSnapShot);
return INVALID_HANDLE_VALUE;
}
bool SetPrivilege( HANDLE hToken,LPCTSTR Privilege, BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp = { 0 };
// Initialize everything to zero
LUID luid;
DWORD cb=sizeof( TOKEN_PRIVILEGES );
if(!LookupPrivilegeValue( NULL, Privilege, &luid ))
return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if(bEnablePrivilege) {
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
} else {
tp.Privileges[0].Attributes = 0;
}
AdjustTokenPrivileges( hToken, FALSE, &tp, cb, NULL, NULL );
if ( GetLastError() != ERROR_SUCCESS )
return FALSE;
return TRUE;
}
//Entry Point Sets Privs... :]
BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD fwdReason, LPVOID lpvReserved)
{
switch(fwdReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
|
[file hkHook.h]
| Code: |
#define _CRT_SECURE_NO_DEPRECATE
#define _X86_
#include <windows.h>
#include <tlhelp32.h>
#include <commctrl.h>
#include <aclapi.h>
#include "HookLib.h"
#define NTSTATUS ULONG
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define ExpAff _declspec(dllexport)
#define PORTCONNECTNAME L"\\BaseNamedObjects\\LPC_SHARE_CONNECT"
#define LPCEVENT L"\\LPC_SHARE_EVENT"
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING, *PANSI_STRING;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef struct ACCESS_TOKEN
{
HANDLE Token;
HANDLE Thread;
} ACCESS_TOKEN;
typedef enum _SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
}SECTION_INHERIT;
struct PE_Header
{
unsigned long signature;
unsigned short machine;
unsigned short numSections;
unsigned long timeDateStamp;
unsigned long pointerToSymbolTable;
unsigned long numOfSymbols;
unsigned short sizeOfOptionHeader;
unsigned short characteristics;
};
struct PE_ExtHeader
{
unsigned short magic;
unsigned char majorLinkerVersion;
unsigned char minorLinkerVersion;
unsigned long sizeOfCode;
unsigned long sizeOfInitializedData;
unsigned long sizeOfUninitializedData;
unsigned long addressOfEntryPoint;
unsigned long baseOfCode;
unsigned long baseOfData;
unsigned long imageBase;
unsigned long sectionAlignment;
unsigned long fileAlignment;
unsigned short majorOSVersion;
unsigned short minorOSVersion;
unsigned short majorImageVersion;
unsigned short minorImageVersion;
unsigned short majorSubsystemVersion;
unsigned short minorSubsystemVersion;
unsigned long reserved1;
unsigned long sizeOfImage;
unsigned long sizeOfHeaders;
unsigned long checksum;
unsigned short subsystem;
unsigned short DLLCharacteristics;
unsigned long sizeOfStackReserve;
unsigned long sizeOfStackCommit;
unsigned long sizeOfHeapReserve;
unsigned long sizeOfHeapCommit;
unsigned long loaderFlags;
unsigned long numberOfRVAAndSizes;
unsigned long exportTableAddress;
unsigned long exportTableSize;
unsigned long importTableAddress;
unsigned long importTableSize;
unsigned long resourceTableAddress;
unsigned long resourceTableSize;
unsigned long exceptionTableAddress;
unsigned long exceptionTableSize;
unsigned long certFilePointer;
unsigned long certTableSize;
unsigned long relocationTableAddress;
unsigned long relocationTableSize;
unsigned long debugDataAddress;
unsigned long debugDataSize;
unsigned long archDataAddress;
unsigned long archDataSize;
unsigned long globalPtrAddress;
unsigned long globalPtrSize;
unsigned long TLSTableAddress;
unsigned long TLSTableSize;
unsigned long loadConfigTableAddress;
unsigned long loadConfigTableSize;
unsigned long boundImportTableAddress;
unsigned long boundImportTableSize;
unsigned long importAddressTableAddress;
unsigned long importAddressTableSize;
unsigned long delayImportDescAddress;
unsigned long delayImportDescSize;
unsigned long COMHeaderAddress;
unsigned long COMHeaderSize;
unsigned long reserved2;
unsigned long reserved3;
};
struct SectionHeader
{
unsigned char sectionName[8];
unsigned long virtualSize;
unsigned long virtualAddress;
unsigned long sizeOfRawData;
unsigned long pointerToRawData;
unsigned long pointerToRelocations;
unsigned long pointerToLineNumbers;
unsigned short numberOfRelocations;
unsigned short numberOfLineNumbers;
unsigned long characteristics;
};
struct MZHeader
{
unsigned short signature;
unsigned short partPag;
unsigned short pageCnt;
unsigned short reloCnt;
unsigned short hdrSize;
unsigned short minMem;
unsigned short maxMem;
unsigned short reloSS;
unsigned short exeSP;
unsigned short chksum;
unsigned short exeIP;
unsigned short reloCS;
unsigned short tablOff;
unsigned short overlay;
unsigned char reserved[32];
unsigned long offsetToPE;
};
struct ImportDirEntry
{
DWORD importLookupTable;
DWORD timeDateStamp;
DWORD fowarderChain;
DWORD nameRVA;
DWORD importAddressTable;
};
typedef struct _LPC_MESSAGE_HEADER
{
WORD DataLength;
WORD TotalLength;
WORD MessageType;
WORD DataInfoOffset;
DWORD ClientPId;
DWORD ClientTId;
DWORD MessageId;
DWORD CallBackId;
}LPC_MESSAGE_HEADER, *PLPC_MESSAGE_HEADER;
typedef struct _LPC_MESSAGE
{
LPC_MESSAGE_HEADER MsgHeader;
BYTE MessageData[255];
}LPC_MESSAGE,*PLPC_MESSAGE;
typedef struct _LPC_SECTION_OWNER_MEMORY {
DWORD Length;
HANDLE SectionHandle;
DWORD OffsetInSection;
DWORD SectionSize;
DWORD ClientBaseAddress;
DWORD ServerBaseAddress;
}LPC_SECTION_OWNER_MEMORY,*PLPC_SECTION_OWNER_MEMORY;
typedef struct _LPC_SECTION_MEMORY
{
DWORD Length;
DWORD SectionSize;
DWORD ServerBaseAddress;
} LPC_SECTION_MEMORY, *PLPC_SECTION_MEMORY;
typedef struct _SECTION_BASIC_INFORMATION
{ // Information Class 0
PVOID BaseAddress;
ULONG Attributes;
LARGE_INTEGER Size;
}SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
typedef enum LPC_MESSAGE_TYPE {
LPC_REQUEST = 0,
LPC_REPLY = 1,
LPC_DATAGRAM = 2,
LPC_LOST_REPLY = 3,
LPC_PORT_CLOSED = 4,
LPC_CLIENT_DIED = 5,
LPC_EXCEPTION = 6,
LPC_DEBUG_EVENT = 7,
LPC_ERROR_EVENT = 8,
LPC_CONNECTION_REQUEST = 9
};
typedef enum SECTION_INFORMATION_CLASS
{
SectionBasicInformation,
SectionImageInformation
};
typedef struct cLLHook {
BYTE Installed;//0 is not installed 1 if installed
BYTE bJmp;//e9 jmp e8 call
LPVOID pHeap;
DWORD TProcessId;//Targets ProcessId
DWORD hkTAddress;//Target Function to Hook
DWORD hkAddress;//Hook
DWORD hkSz;//our hook size generally 5 bytes byte+dword
cLLHook *NextHook;//ptr to Next Hook In List..
cLLHook()//initialize everything to 0
{
Installed = 0;
bJmp = 0;
pHeap = 0;
TProcessId = 0;
hkTAddress = 0;
hkAddress = 0;
hkSz = 0;
NextHook = 0;
}
}cLLHook, *PcLLHook;
byte DataBuffer[0x100];
static HANDLE hLPCEventPair;
HANDLE hClientLPCEventPair = INVALID_HANDLE_VALUE;
OBJECT_ATTRIBUTES oa;
SECURITY_QUALITY_OF_SERVICE qos;
UNICODE_STRING UString;
HANDLE hServerConnectionPort;
DWORD DataSize = sizeof(DataBuffer);
DWORD ClientPid,ClientTid;
LPC_MESSAGE LPCMSG;
LPC_SECTION_OWNER_MEMORY SectOwner;
LPC_SECTION_MEMORY SectMemory;
NTSTATUS Status;
extern "C"
{
bool SetPrivilege(
__in HANDLE hToken, // token handle
__in LPCTSTR Privilege, // Privilege to enable/disable
__in BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
);
ExpAff HANDLE UsrDrOpenProcess(
__in char *ProcN
);
bool UsrReadPEInfo(
__in char*,
__in MZHeader*,
__in PE_Header*,
__in PE_ExtHeader*,
__in SectionHeader**
);
int UsrCalcImageSize(
__in MZHeader*,
__in PE_Header*,
__in PE_ExtHeader*,
__in SectionHeader*
);
ExpAff bool UsrLoadFile(
__in char*,
__in MZHeader*,
__in PE_Header*,
__in PE_ExtHeader*,
__in SectionHeader*,
__inout LPVOID
);
unsigned long UsrGetAlignedSize(
__in unsigned long,
__in unsigned long
);
//Zero's a buffer PBYTE buffer , DWORD BufferSize
ExpAff LPVOID CleanBuffer(
__in PBYTE,
__in DWORD
);
//Places files into share Provided Full FilePath
ExpAff LPVOID UsrShareFile(
__in char*
);
//LPCSTR DllName, char* ApiName
//returns 0 on fail and non API Address on success
ExpAff DWORD UsrGetProcAddr(
__in LPCSTR ,
__in char*
);
//DWORD ProcessId,char*DllName,char MODULE Name
ExpAff DWORD UsrGetRemoteProcAddr(
__in DWORD,
__in char*,
__in char*
);
ExpAff bool UsrHotPatchAddr(
__in char *,
__in char*,
__in LPVOID,
__in LPVOID*
);
ExpAff bool UsrHotUnpatch(
__in void*
);
ExpAff PcLLHook UsrHkInit(
__in char* ProcessName
);
ExpAff PcLLHook UsrSetHkParams(
__in DWORD tAddr,
__in DWORD HkAddr,
__in DWORD HkSz,
__in cLLHook *HkStruct
);
ExpAff bool UsrInstallHook(
__in PcLLHook HkParams
);
}
DWORD myStrlenA(char *ptr)
{
DWORD len = 0;
while(*ptr)
{
len++;
ptr++;
}
return len;
}
BOOL myStrcmpA(char *str1, char *str2)
{
while(*str1 && *str2)
{
if(*str1 == *str2)
{
str1++;
str2++;
}
else
{
return FALSE;
}
}
if(*str1 && !*str2)
{
return FALSE;
}
else if(*str2 && !*str1)
{
return FALSE;
}
return TRUE;
}
extern "C"
{
//Import API
NTSYSAPI
void
NTAPI
RtlInitUnicodeString(
IN OUT PUNICODE_STRING DestinationStr,
IN PCWSTR InputString
);
NTSYSAPI
NTSTATUS
NTAPI
ZwCompleteConnectPort(
HANDLE PortHandle
);
NTSYSAPI
NTSTATUS
NTAPI
NtCreatePort(
PHANDLE PortHandle,
POBJECT_ATTRIBUTES ObjectAttributes,
ULONG MaxConnectInfoLength,
ULONG MaxDataLength,
PULONG Reserved
);
NTSYSAPI
NTSTATUS
NTAPI
NtAcceptConnectPort(
PHANDLE ServerPortHandle,
HANDLE AlternativeReceivePortHandle OPTIONAL,
PLPC_MESSAGE ConnectionReply,
BOOLEAN AcceptConnection,
PLPC_SECTION_OWNER_MEMORY ServerSharedMemory OPTIONAL,
PLPC_SECTION_MEMORY ClientSharedMemory
);
NTSYSAPI
NTSTATUS
NTAPI
NtReplyWaitReceivePort(
HANDLE PortHandle,
PHANDLE ReceivePortHandle,
PLPC_MESSAGE Reply,
PLPC_MESSAGE IncomingRequest
);
NTSYSAPI
NTSTATUS
NTAPI
NtCreateEventPair(
PHANDLE EventPairHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes
);
NTSYSAPI
NTSTATUS
NTAPI
NtOpenSection(
OUT PHANDLE SectionHandle,
IN DWORD DesiredAccess,
IN POBJECT_ATTRIBUTES ObjAttr
);
NTSYSAPI
NTSTATUS
NTAPI
NtCreateSection(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER MaximumSize OPTIONAL,
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN HANDLE FileHandle OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
NtMapViewOfSection(
IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG_PTR ZeroBits,
IN SIZE_T CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PSIZE_T ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Win32Protect
);
NTSYSAPI
NTSTATUS
NTAPI
NtSetInformationThread(
HANDLE ThreadHandle,
DWORD ThreadInfoClass,
PVOID ThreadInformation,
ULONG ThreadInformationLength
);
NTSYSAPI
NTSTATUS
NTAPI
NtUnmapViewOfSection(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySection(
IN HANDLE SectionHandle,
IN SECTION_INFORMATION_CLASS SectionInformationClass,
OUT PVOID SectionInformation,
IN ULONG SectionInformationLength,
OUT PULONG ResultLength OPTIONAL
);
}
namespace hkHook
{
extern "C"
{
ExpAff bool hkHookCreate();//Constructor
ExpAff bool hkHookDestroy();//Destructor
ExpAff PcLLHook hkAddEntryForHook();//Adds another hook to our Linked List
ExpAff bool hkSetTargetExeName(__in char *);//Sets Global Exe Name used for process opening by exe name...
ExpAff PcLLHook hkPrevious(__in PcLLHook);//gets previose hook structure
ExpAff void hkDeleteNode(__in PcLLHook);//Delete hook link off our list
ExpAff HANDLE hkInitSection();//Initializes Our Shared Section
ExpAff bool hkInitServer();
ExpAff bool hkConnectRequest(__in PLPC_MESSAGE,__inout PHANDLE);
char *cProcessName;//current target process name..
HANDLE hHeap;
PcLLHook hkHead,hkTail,hkCurrentPtr;
PcLLHook PLLHook;//temp placeholder for hooking class
bool hkHookCreate()
{
hkHook::hHeap = HeapCreate(0,sizeof(cLLHook),0);//Initialize hkHead hkTail hkCurrent to a new Structure
if(hkHook::hHeap != INVALID_HANDLE_VALUE)
{
hkCurrentPtr = hkHook::hkTail = hkHook::hkHead = (PcLLHook)hkHook::hHeap;//make head equal ass to create linked List
return true;
}
return false;
}
//the destructor
bool hkHookDestroy()
{
if(HeapDestroy(hkHook::hHeap) == 1)
{
return true;
}
return false;
}
//returns pointer to new cLL Structure..
PcLLHook hkAddEntryForHook()
{
hkHook::hkTail->pHeap = HeapAlloc(hkHook::hHeap,HEAP_ZERO_MEMORY,sizeof(cLLHook));
hkHook::hkTail=hkHook::hkTail->NextHook = (cLLHook*)hkHook::hkTail->pHeap;
return (PcLLHook)hkHook::hkTail;
}
bool hkSetTargetExeName(char *TargetProcName)
{
if(TargetProcName)
{
hkHook::cProcessName = TargetProcName;
return true;
}
return false;
}
PcLLHook hkPrevious(PcLLHook index)
{
hkHook::PLLHook=hkHook::hkHead;
if(index==hkHook::hkHead) //special case, index IS the head :)
{
return hkHook::hkHead;
}
while(hkHook::PLLHook->NextHook != index)
{
hkHook::PLLHook=hkHook::PLLHook->NextHook;
}
return hkHook::PLLHook;
}
void hkDeleteNode(PcLLHook DeadNode) //<-- i thought it was funny :)
{
if(DeadNode == hkHook::hkHead) //case 1 corpse = Head
{
hkHook::PLLHook=hkHook::hkHead;
hkHook::hkHead=hkHook::hkHead->NextHook;
HeapFree(hkHook::hHeap,0,hkHook::PLLHook->pHeap);
}
else if(DeadNode == hkHook::hkTail) //case 2 corpse is at the end
{
hkHook::PLLHook=hkHook::hkPrevious(DeadNode);
hkHook::PLLHook->NextHook=NULL;
HeapFree(hkHook::hHeap,0,hkHook::PLLHook->pHeap);
hkHook::hkTail=hkHook::PLLHook;
}
else //case 3 corpse is in middle somewhere
{
hkHook::PLLHook=hkHook::hkPrevious(DeadNode);
hkHook::PLLHook->NextHook=DeadNode->NextHook;
HeapFree(hkHook::hHeap,0,DeadNode->pHeap);
}
hkHook::hkCurrentPtr=hkHook::PLLHook; //Reset the class CurrentPtr
}
LPVOID CleanBuffer(PBYTE DataBuffer,DWORD DataBufferSize)
{
LPVOID MemPtr;
MemPtr = memset(DataBuffer,0,DataBufferSize);
if(!MemPtr)
{
MemPtr = 0;
return MemPtr;
}
return MemPtr;
}
HANDLE hkInitSection()//Shared section Initialization Function
{
HANDLE SecObj = INVALID_HANDLE_VALUE;
LARGE_INTEGER SecSize;
SecSize.LowPart = 0x10000;
SecSize.HighPart = 0x0;
Status = NtCreateSection(&SecObj,SECTION_ALL_ACCESS,NULL,&SecSize,PAGE_READWRITE,SEC_COMMIT,NULL);
if(!NT_SUCCESS(Status))
{
return SecObj;
}
memset(&oa,0,sizeof(OBJECT_ATTRIBUTES));
oa.Length = sizeof(OBJECT_ATTRIBUTES);
RtlInitUnicodeString(&UString,LPCEVENT);
oa.ObjectName = &UString;
Status = NtCreateEventPair(&hLPCEventPair,STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE ,&oa);
if(!NT_SUCCESS(Status))
{
return SecObj;
}
Status = NtSetInformationThread(GetCurrentThread(),8,&hLPCEventPair,4);
if(!NT_SUCCESS(Status))
{
return SecObj;
}
return SecObj;
}
//much work needed here :P im coming though..
bool hkConnectRequest(PLPC_MESSAGE LpcMessage,PHANDLE pAcceptPortHandle)
{
*pAcceptPortHandle=NULL;
Status = NtReplyWaitReceivePort(hServerConnectionPort,NULL,NULL,&LPCMSG);
if(!NT_SUCCESS(Status))
{
return FALSE;
}
if(LpcMessage->MsgHeader.MessageType == LPC_CONNECTION_REQUEST)
{
Status = NtAcceptConnectPort(&hServerConnectionPort,0,&LPCMSG,1,&SectOwner,NULL);
if(!NT_SUCCESS(Status))
{
return FALSE;
}
Status = ZwCompleteConnectPort(hServerConnectionPort);
if (!NT_SUCCESS(Status))
{
CloseHandle(hServerConnectionPort);
return FALSE;
}
*pAcceptPortHandle = hServerConnectionPort;
return TRUE;
}
return FALSE;
}
bool hkInitServer()
{
HANDLE SecObj = hkInitSection();
SECTION_BASIC_INFORMATION SecBasInfo;
ULONG nResultLen = 0;
if(SecObj == INVALID_HANDLE_VALUE)
{
return FALSE;
}
CleanBuffer((BYTE*)&SectOwner,sizeof(LPC_SECTION_OWNER_MEMORY));
memset(&SectMemory,0,sizeof(LPC_SECTION_MEMORY));
memset(&oa,0,sizeof(OBJECT_ATTRIBUTES));
SectOwner.Length = sizeof(LPC_SECTION_OWNER_MEMORY);
SectOwner.SectionHandle = SecObj;
ZwQuerySection(SecObj,SectionBasicInformation,&SecBasInfo,sizeof(SECTION_BASIC_INFORMATION),&nResultLen);
if(nResultLen)
{
SectOwner.SectionSize = SecBasInfo.Size.LowPart;
oa.Length = sizeof(OBJECT_ATTRIBUTES);
RtlInitUnicodeString(&UString, PORTCONNECTNAME);
oa.ObjectName = &UString;
Status = NtCreatePort(&hServerConnectionPort,&oa,40,sizeof(LPC_MESSAGE),0x0);
if(!NT_SUCCESS(Status))
{
return FALSE;
}
return TRUE;
}
return FALSE;
}
}
}
|
please post comment and ideas ;]
Greets BanMe
|
|