Example #1
0
VOID scanSendChatMessage_ScanProc(INT iItem, HWND hwndDlg, PBYTE pbFile)
{
	PIMAGE_NT_HEADERS pNtHdr = PIMAGE_NT_HEADERS(pbFile + PIMAGE_DOS_HEADER(pbFile)->e_lfanew);
    PIMAGE_SECTION_HEADER pSecHdr = PIMAGE_SECTION_HEADER(pNtHdr + 1);
    PBYTE pbCode = RvaToPointer(pbFile, pSecHdr[0].VirtualAddress);
    DWORD dwCodeSize = pSecHdr[0].SizeOfRawData;
	PBYTE pbRData = RvaToPointer(pbFile, pSecHdr[1].VirtualAddress);
	DWORD dwRDataSize = pSecHdr[1].SizeOfRawData;
	PBYTE pbData = RvaToPointer(pbFile, pSecHdr[2].VirtualAddress);
    DWORD dwDataSize = pSecHdr[2].SizeOfRawData;
	
	SetItemStatus(iItem, hwndDlg, "Scanning...");

	// scan data section for "Unknown chat type"
	for(DWORD dwDataIndex = 0; dwDataIndex < dwDataSize - (sizeof("Unknown chat type") - 1); dwDataIndex++)
	{
		if(MemoryCompare(&pbData[dwDataIndex], (PBYTE)"Unknown chat type", sizeof("Unknown chat type") - 1))
		{
			// calculate va of found string
			DWORD dwStringVA = OffsetToRva(pbFile, PtrToUlong(pbData) + dwDataIndex - PtrToUlong(pbFile));
			if(dwStringVA)
			{
				dwStringVA += pNtHdr->OptionalHeader.ImageBase;

				// scan code section for 'push dwStringVA'
				for(DWORD dwCodeIndex = 0; dwCodeIndex < dwCodeSize - 8; dwCodeIndex++)
				{
					if(pbCode[dwCodeIndex] == 0x68 && *((PDWORD)&pbCode[dwCodeIndex + 1]) == dwStringVA)
					{
						// find beginning of procedure
						for(DWORD dwCodeIndex2 = dwCodeIndex & 0xFFFFFFF0; dwCodeIndex2; dwCodeIndex2 -= 0x10)
						{
							if(pbCode[dwCodeIndex2 - 1] == 0x90 || pbCode[dwCodeIndex2 - 1] == 0xC3 || pbCode[dwCodeIndex2 - 3] == 0xC2)
							{
								DWORD dwProcRva = OffsetToRva(pbFile, PtrToUlong(pbCode) + dwCodeIndex2 - PtrToUlong(pbFile));
								if(dwProcRva)
								{
									GetPPD(iItem, hwndDlg)->dwValue = dwProcRva + pNtHdr->OptionalHeader.ImageBase;
									SetItemStatus(iItem, hwndDlg, "Success");
									return;
								}
							}
						}
					}
				}
			}
		}
	}
	GetPPD(iItem, hwndDlg)->dwValue = 0;
	SetItemStatus(iItem, hwndDlg, "Fail");
}
BOOL CRemoteLoader::ProcessTlsEntries( PVOID BaseAddress, PVOID RemoteAddress )
{
	IMAGE_NT_HEADERS* ImageNtHeaders = ToNts( BaseAddress );

	if( ImageNtHeaders == NULL ) 
		return FALSE;

	if( ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_TLS ].Size == 0 )
		return TRUE; // Success when there is no Tls Entries

	DebugShout( "[ProcessTlsEntries] Tls Data detected!" );

	IMAGE_TLS_DIRECTORY* TlsDirectory =
		( IMAGE_TLS_DIRECTORY* ) RvaToPointer( ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_TLS ].VirtualAddress, BaseAddress );

	if( TlsDirectory == NULL )
		return TRUE; // Success when there is no Tls entries / broken data?

	DebugShout( "[ProcessTlsEntries] TlsDirectory (0x%X)", 
		TlsDirectory );

	if( TlsDirectory->AddressOfCallBacks == NULL )
		return TRUE; // Success when there is no Tls entries / broken data?

	DebugShout( "[ProcessTlsEntries] TlsDirectory->AddressOfCallBacks (0x%X)", 
		TlsDirectory->AddressOfCallBacks );

	PIMAGE_TLS_CALLBACK TLSCallbacks[ 0xFF ];

	if( ReadProcessMemory( GetProcess(), ( LPCVOID ) TlsDirectory->AddressOfCallBacks, TLSCallbacks, sizeof( TLSCallbacks ), NULL ) == FALSE )
	{
		DebugShout( "[ProcessTlsEntries] Failed ReadProcessMemory" );

		return FALSE;
	}

	BOOL SuccessValue = TRUE;

	for( int i = 0; TLSCallbacks[i]; i++ )
	{
		DebugShout( "[ProcessTlsEntries] TLSCallbacks[%i] = 0x%X (0x%X)", i, TLSCallbacks[i], RemoteAddress );

		// As a consequence of the relocation stuff mentioned above, pCallbacks[i] is already fixed

		if( CallEntryPoint( RemoteAddress, ( FARPROC ) TLSCallbacks[i] ) == false )
		{
			DebugShout( "[ProcessTlsEntries] Failed to execute Tls Entry [%i]", i );
		}
		else
		{
			DebugShout( "[ProcessTlsEntries] Called Tls Callback (0x%X)", TLSCallbacks[i] );
		}
	}

	return SuccessValue;
}
Example #3
0
VOID scanZeroGravity_ScanProc(INT iItem, HWND hwndDlg, PBYTE pbFile)
{
	PIMAGE_NT_HEADERS pNtHdr = PIMAGE_NT_HEADERS(pbFile + PIMAGE_DOS_HEADER(pbFile)->e_lfanew);
    PIMAGE_SECTION_HEADER pSecHdr = PIMAGE_SECTION_HEADER(pNtHdr + 1);
    PBYTE pbCode = RvaToPointer(pbFile, pSecHdr[0].VirtualAddress);
    DWORD dwCodeSize = pSecHdr[0].SizeOfRawData;
	PBYTE pbRData = RvaToPointer(pbFile, pSecHdr[1].VirtualAddress);
	DWORD dwRDataSize = pSecHdr[1].SizeOfRawData;
	PBYTE pbData = RvaToPointer(pbFile, pSecHdr[2].VirtualAddress);
    DWORD dwDataSize = pSecHdr[2].SizeOfRawData;
	
	SetItemStatus(iItem, hwndDlg, "Scanning...");

	// scan for 'and reg, 75BFEDFF'
	for(DWORD dwCodeIndex = 0; dwCodeIndex < dwCodeSize - 6; dwCodeIndex++)
	{
		if(*((PDWORD)&pbCode[dwCodeIndex]) == 0x75BFEDFF && (pbCode[dwCodeIndex - 1] == 0x25 || ((pbCode[dwCodeIndex - 1] & 0xF8) == 0xE0 && pbCode[dwCodeIndex - 2] == 0x81)))
		{
			// search for long jump or call following and instruction
			for(DWORD dwCodeIndex2 = dwCodeIndex + 4; dwCodeIndex2 - dwCodeIndex < 20; dwCodeIndex2++)
			{
				if(pbCode[dwCodeIndex2] == 0xE9 || pbCode[dwCodeIndex2] == 0xE8)
				{
					// get offset of jump location
					DWORD dwJumpOffset = (dwCodeIndex2 + 5) + *((PDWORD)&pbCode[dwCodeIndex2 + 1]);
					
					// scan for 'test [reg+disp], 4000000h'
					for(DWORD dwCodeIndex3 = dwJumpOffset; dwCodeIndex3 - dwJumpOffset < 500; dwCodeIndex3++)
					{
						if(*((PDWORD)&pbCode[dwCodeIndex3]) == 0x04000000)
						{
							if(pbCode[dwCodeIndex3 - 3] == 0xF7) // short displacement
							{
								// find a je to this instruction
								for(DWORD dwCodeIndex4 = dwCodeIndex3 - 5; dwCodeIndex4 >= dwJumpOffset; dwCodeIndex4--)
								{
									if(pbCode[dwCodeIndex4] == 0x74 && pbCode[dwCodeIndex4+1] == ((dwCodeIndex3 - 3) - (dwCodeIndex4 + 2)))
									{
										// search for 'mov [reg+disp], reg' above the jump
										for(DWORD dwCodeIndex5 = dwCodeIndex4; dwCodeIndex5 >= dwJumpOffset; dwCodeIndex5--)
										{
											if(pbCode[dwCodeIndex5] == 0x89)
											{
												// search for 'mov reg, [reg+disp]
												for(DWORD dwCodeIndex6 = dwCodeIndex5; dwCodeIndex6 >= dwJumpOffset; dwCodeIndex6--)
												{
													if(pbCode[dwCodeIndex6] == 0x8B && (pbCode[dwCodeIndex6+1] & 0x38) == (pbCode[dwCodeIndex5+1] & 0x38))
													{
														GetPPD(iItem, hwndDlg)->dwValue = OffsetToRva(pbFile, PtrToUlong(pbCode) + dwCodeIndex - PtrToUlong(pbFile)) + pNtHdr->OptionalHeader.ImageBase;
														SetItemStatus(iItem, hwndDlg, "Success");
														return;
													}
												}
											}
										}
									}
								}
							}
							else if(pbCode[dwCodeIndex3 - 6] == 0xF7) // long displacement
							{
								// find a je to this instruction
								for(DWORD dwCodeIndex4 = dwCodeIndex3 - 8; dwCodeIndex4 >= dwJumpOffset; dwCodeIndex4--)
								{
									if(pbCode[dwCodeIndex4] == 0x74 && pbCode[dwCodeIndex4+1] == ((dwCodeIndex3 - 6) - (dwCodeIndex4 + 2)))
									{
										// search for mov '[reg+disp], reg' above the jump
										for(DWORD dwCodeIndex5 = dwCodeIndex4; dwCodeIndex5 >= dwJumpOffset; dwCodeIndex5--)
										{
											if(pbCode[dwCodeIndex5] == 0x89)
											{
												// search for 'mov reg, [reg+disp]
												for(DWORD dwCodeIndex6 = dwCodeIndex5; dwCodeIndex6 >= dwJumpOffset; dwCodeIndex6--)
												{
													if(pbCode[dwCodeIndex6] == 0x8B && (pbCode[dwCodeIndex6+1] & 0x38) == (pbCode[dwCodeIndex5+1] & 0x38))
													{
														GetPPD(iItem, hwndDlg)->dwValue = OffsetToRva(pbFile, PtrToUlong(pbCode) + dwCodeIndex - PtrToUlong(pbFile)) + pNtHdr->OptionalHeader.ImageBase;
														SetItemStatus(iItem, hwndDlg, "Success");
														return;
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}

	GetPPD(iItem, hwndDlg)->dwValue = 0;
	SetItemStatus(iItem, hwndDlg, "Fail");
}
BOOL CRemoteLoader::ProcessRelocations( PVOID BaseAddress, PVOID RemoteAddress )
{
	IMAGE_NT_HEADERS* ImageNtHeaders = ToNts( BaseAddress );

	if( ImageNtHeaders == NULL )
		return FALSE;

	if( ImageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED )
	{
		DebugShout( "[ProcessRelocations] Relocations have been stripped from this executable, continuing.." );

		return TRUE;
	}
	else
	{
		DWORD ImageBaseDelta = MakeDelta( DWORD, RemoteAddress, ImageNtHeaders->OptionalHeader.ImageBase );

		DebugShout( "[ProcessRelocations] VirtualAddress (0x%X)",
			ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress );

		DWORD RelocationSize = ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].Size;

		DebugShout( "[ProcessRelocations] Relocation Size [0x%X]", RelocationSize );

		if( RelocationSize )
		{
			IMAGE_BASE_RELOCATION* RelocationDirectory = ( IMAGE_BASE_RELOCATION* ) 
				RvaToPointer( ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress, BaseAddress );

			if( RelocationDirectory )
			{
				DebugShout( "[ProcessRelocations] RelocationDirectory (0x%X)", RelocationDirectory );

				PVOID RelocationEnd = reinterpret_cast< PBYTE >( RelocationDirectory ) + RelocationSize;

				while( RelocationDirectory < RelocationEnd )
				{
					PBYTE RelocBase = static_cast< PBYTE >( RvaToPointer( RelocationDirectory->VirtualAddress, BaseAddress ) );

					DWORD NumRelocs = ( RelocationDirectory->SizeOfBlock - sizeof( IMAGE_BASE_RELOCATION ) ) / sizeof( WORD ); 

					PWORD RelocationData = reinterpret_cast< PWORD >( RelocationDirectory + 1 );

					DebugShout( "[ProcessRelocations] RelocationDirectory (0x%X)", RelocationDirectory );
					DebugShout( "[ProcessRelocations] RelocationData (0x%X)", RelocationData );

					 for( DWORD i = 0; i < NumRelocs; ++i, ++RelocationData )
					 {
						 if( ProcessRelocation( ImageBaseDelta, *RelocationData, RelocBase ) == FALSE )
						 {
							 DebugShout( "[ProcessRelocations] Unable to process relocation (%i)", i );
						 }
					 }

					RelocationDirectory = reinterpret_cast< PIMAGE_BASE_RELOCATION >( RelocationData );
				}
			}
			else
			{
				DebugShout( "[ProcessRelocations] Relocations have a size, but the pointer is invalid" );

				return FALSE;
			}
		}
		else
		{
			DebugShout( "[ProcessRelocations] Relocations have have not been found in this executable, continuing.." );

			return TRUE;
		}
	}

	return TRUE;
}
BOOL CRemoteLoader::ProcessImportTable( PVOID BaseAddress, PVOID RemoteAddress, PCHAR OptionalPath )
{
	IMAGE_NT_HEADERS* ImageNtHeaders = ToNts( BaseAddress );

	if( ImageNtHeaders == NULL )
		return FALSE;

	if( ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].Size )
	{
		IMAGE_IMPORT_DESCRIPTOR* ImageImportDescriptor = ( IMAGE_IMPORT_DESCRIPTOR* )
			RvaToPointer( ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress, BaseAddress );

		if( ImageImportDescriptor )
		{
			for( ; ImageImportDescriptor->Name; ImageImportDescriptor++ )
			{
				PCHAR ModuleName = ( PCHAR ) RvaToPointer( ImageImportDescriptor->Name, BaseAddress );

				if( ModuleName == NULL )
				{
					DebugShout( "[ProcessImportTable] Module name for entry NULL" );

					continue;
				}

				DebugShout( "[ProcessImportTable] Module Name [%s]", ModuleName );

				HMODULE ModuleBase = GetRemoteModuleHandleA( ModuleName );

				if( ModuleBase == NULL )
				{
					ModuleBase = LoadLibraryByPathA( ModuleName );
				}

				if( ModuleBase == NULL )
				{
					DebugShout( "[ProcessImportTable] Failed to obtain module handle [%s]", ModuleName );

					continue;
				}

				IMAGE_THUNK_DATA *ImageThunkData	= NULL;
				IMAGE_THUNK_DATA *ImageFuncData		= NULL;

				if( ImageImportDescriptor->OriginalFirstThunk )
				{
					ImageThunkData	= ( IMAGE_THUNK_DATA* ) RvaToPointer( ImageImportDescriptor->OriginalFirstThunk, BaseAddress );
					ImageFuncData	= ( IMAGE_THUNK_DATA* ) RvaToPointer( ImageImportDescriptor->FirstThunk, BaseAddress );
				}
				else
				{
					ImageThunkData	= ( IMAGE_THUNK_DATA* ) RvaToPointer( ImageImportDescriptor->FirstThunk, BaseAddress );
					ImageFuncData	= ( IMAGE_THUNK_DATA* ) RvaToPointer( ImageImportDescriptor->FirstThunk, BaseAddress );
				}

				
				if( ImageThunkData == NULL )
				{
					DebugShout( "[ProcessImportTable] Image Thunk Data is NULL" );
				}

				if( ImageFuncData == NULL )
				{
					DebugShout( "[ProcessImportTable] Image Func Data is NULL" );
				}

				for( ; ImageThunkData->u1.AddressOfData; ImageThunkData++, ImageFuncData++ )
				{
					FARPROC FunctionAddress = NULL;

					if( IMAGE_SNAP_BY_ORDINAL( ImageThunkData->u1.Ordinal ) )
					{
						SHORT Ordinal = ( SHORT ) IMAGE_ORDINAL( ImageThunkData->u1.Ordinal );

						FunctionAddress = ( FARPROC ) GetRemoteProcAddress( ModuleName, Ordinal );

						DebugShout( "[ProcessImportTable] Processed (%s -> %i) -> (0x%X)", 
							ModuleName, Ordinal, FunctionAddress );

						if( this->GetProcess() == INVALID_HANDLE_VALUE )
						{
							DebugShout( "[ProcessImportTable] Normal Value (0x%X)",
								GetProcAddress( GetModuleHandleA( ModuleName ), ( LPCSTR ) Ordinal ) );
						}
					}
					else
					{
						IMAGE_IMPORT_BY_NAME* ImageImportByName = ( IMAGE_IMPORT_BY_NAME* )
							RvaToPointer( *( DWORD* ) ImageThunkData, BaseAddress );

						PCHAR NameOfImport = ( PCHAR ) ImageImportByName->Name;

						FunctionAddress = ( FARPROC ) GetRemoteProcAddress( ModuleName, NameOfImport );

						DebugShout( "[ProcessImportTable] Processed (%s -> %s) -> (0x%X)", 
							ModuleName, NameOfImport, FunctionAddress );

						if( this->GetProcess() == INVALID_HANDLE_VALUE )
						{
							DebugShout( "[ProcessImportTable] Normal Value (0x%X)",
								GetProcAddress( GetModuleHandleA( ModuleName ), NameOfImport ) );
						}
					}

					ImageFuncData->u1.Function = ( DWORD ) FunctionAddress;
				}
			}

			return TRUE;
		}
		else
		{
			DebugShout( "[ProcessImportTable] Size of table confirmed but pointer to data invalid!" );

			return FALSE;
		}
	}
	else
	{
		DebugShout( "[ProcessImportTable] No Imports" );

		return TRUE;
	}

	return FALSE;
}
Example #6
0
VOID scanGetCharacterGuid_ScanProc(INT iItem, HWND hwndDlg, PBYTE pbFile)
{
	PIMAGE_NT_HEADERS pNtHdr = PIMAGE_NT_HEADERS(pbFile + PIMAGE_DOS_HEADER(pbFile)->e_lfanew);
    PIMAGE_SECTION_HEADER pSecHdr = PIMAGE_SECTION_HEADER(pNtHdr + 1);
    PBYTE pbCode = RvaToPointer(pbFile, pSecHdr[0].VirtualAddress);
    DWORD dwCodeSize = pSecHdr[0].SizeOfRawData;
	PBYTE pbRData = RvaToPointer(pbFile, pSecHdr[1].VirtualAddress);
	DWORD dwRDataSize = pSecHdr[1].SizeOfRawData;
	PBYTE pbData = RvaToPointer(pbFile, pSecHdr[2].VirtualAddress);
    DWORD dwDataSize = pSecHdr[2].SizeOfRawData;
	
	SetItemStatus(iItem, hwndDlg, "Scanning...");

	// scan data section for "Player_C.h"
	for(DWORD dwDataIndex = 0; dwDataIndex < dwDataSize - (sizeof("Player_C.h") - 1); dwDataIndex++)
	{
		if(MemoryCompare(&pbData[dwDataIndex], (PBYTE)"Player_C.h", sizeof("Player_C.h") - 1))
		{
			// found "Player_C.h", now scan for beginning of the string
			DWORD dwStringIndex;
			for(dwStringIndex = dwDataIndex - 1; dwStringIndex && pbData[dwStringIndex] >= 0x20 && pbData[dwStringIndex] <= 0x7E; dwStringIndex--);
			dwStringIndex++;

			// calculate va of found string
			DWORD dwStringVA = OffsetToRva(pbFile, PtrToUlong(pbData) + dwStringIndex - PtrToUlong(pbFile));
			if(dwStringVA)
			{
				dwStringVA += pNtHdr->OptionalHeader.ImageBase;

				// scan code section for 'mov edx, dwStringVA'
				BYTE bMoveIns[5];
				bMoveIns[0] = 0xBA;
				*((PDWORD)&bMoveIns[1]) = dwStringVA;
				for(DWORD dwCodeIndex = 0; dwCodeIndex < dwCodeSize - sizeof(bMoveIns); dwCodeIndex++)
				{
					if(MemoryCompare(&pbCode[dwCodeIndex], bMoveIns, sizeof(bMoveIns)))
					{
						// found mov instruction, make sure next instruction is 'mov ecx, constant'
						if(pbCode[dwCodeIndex + 5] == 0xB9)
						{
							// make sure instruction following 'mov ecx, constant' is a call relative
							if(pbCode[dwCodeIndex + 10] == 0xE8)
							{
								// somewhere before the 'mov edx, dwStringVA' instruction there must be this code:
								// call relative
								// push edx
								// push eax
								for(DWORD dwCodeIndex2 = dwCodeIndex - 2; dwCodeIndex - dwCodeIndex2 < 20; dwCodeIndex2--)
								{
									if(*((PWORD)&pbCode[dwCodeIndex2]) == 0x5052 && pbCode[dwCodeIndex2 - 5] == 0xE8)
									{
										// lastly check for a 'push constant' instruction before those two register pushes instruction
										for(DWORD dwCodeIndex3 = dwCodeIndex2 - 5; dwCodeIndex2 - dwCodeIndex3 < 20; dwCodeIndex3--)
										{
											if(pbCode[dwCodeIndex3] == 0x68)
											{
												// we need to decode the call relative preceeding the two register pushes
												
												// calculate va of next instruction following call
												DWORD dwFollowingVA = OffsetToRva(pbFile, PtrToUlong(pbCode) + dwCodeIndex2 - PtrToUlong(pbFile)) + pNtHdr->OptionalHeader.ImageBase;
												if(dwFollowingVA)
												{
													GetPPD(iItem, hwndDlg)->dwValue = dwFollowingVA + *((PDWORD)&pbCode[dwCodeIndex2 - 4]);
													SetItemStatus(iItem, hwndDlg, "Success");
													return;
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	GetPPD(iItem, hwndDlg)->dwValue = 0;
	SetItemStatus(iItem, hwndDlg, "Fail");
}