So, I wondered why I am not able to do memcpy for myself. This is the code that works and gets me the correct result:
unsigned int VTableAddress = FindPattern( VTABLE_PATTERN, VTABLE_MASK );
unsigned int *p_VTable = NULL;
WriteMemory( &p_VTable, ( void* ) ( VTableAddress + 2 ), 4 );
//....
void D3DX9Interface::WriteMemory( void *address, void *bytes, int byteSize )
{
DWORD NewProtection;
VirtualProtect( address, byteSize, PAGE_EXECUTE_READWRITE, &NewProtection );
memcpy( address, bytes, byteSize );
VirtualProtect( address, byteSize, NewProtection, &NewProtection );
}
So for my understanding, WriteMemory basically sets read/write protection to the memory address and then simply copies bytes into address. To understand how things are working, I've tried it myself with this code:
//Get the address of the vtable
unsigned int VTableAddress = FindPattern( VTABLE_PATTERN, VTABLE_MASK );
unsigned int *p_VTable = NULL;
CopyWithRWPrivileges( p_VTable, (unsigned int*)( VTableAddress + 2 ) );
//...
void D3DX9Interface::CopyWithRWPrivileges( unsigned int *p_Destination, unsigned int *p_Source )
{
DWORD Protection( 0 );
VirtualProtect( reinterpret_cast< LPVOID >( p_Destination ), 4, PAGE_EXECUTE_READWRITE, &Protection );
p_Destination = p_Source;
VirtualProtect( reinterpret_cast< LPVOID >( p_Destination ), 4, Protection, &Protection );
}
But for some reason the last code gives me back a NULL pointer. But why?
Ok with the help of UnholySheep I've found the solution for my problem. So first, the pointer is getting copied instead of passed as a reference-pointer. And as second, the p_Source needs to be handled as a pointer too, so with this code it's working:
void D3DX9Interface::CopyWithRWPrivileges( unsigned int *&p_Destination, unsigned int *p_Source )
{
DWORD Protection( 0 );
VirtualProtect( reinterpret_cast< LPVOID >( p_Destination ), 4, PAGE_EXECUTE_READWRITE, &Protection );
p_Destination = *(unsigned int**) p_Source;
VirtualProtect( reinterpret_cast< LPVOID >( p_Destination ), 4, Protection, &Protection );
}
Related
I'm trying to modify the RCData of a compiled AutoHotkey script:
void ReplaceStringTable() {
HANDLE hRes = BeginUpdateResource( _T( "C:\\Users\\CAIO\\Documents\\Github\\main\\scripts\\ahkDebug\\Novo(a) AutoHotkey Script.exe" ), FALSE );
if ( hRes != NULL ) {
std::wstring data[] = { L"MsgBox Test" };
std::vector< WORD > buffer;
for ( size_t index = 0;
index < sizeof( data ) / sizeof( data[ 0 ] );
++index ) {
size_t pos = buffer.size();
buffer.resize( pos + data[ index ].size() + 1 );
buffer[ pos++ ] = static_cast< WORD >( data[ index ].size() );
copy( data[ index ].begin(), data[ index ].end(),
buffer.begin() + pos );
}
UpdateResource( hRes,
RT_RCDATA,
L">AUTOHOTKEY SCRIPT<", //MAKEINTRESOURCE( 1 ),
1033, //MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
reinterpret_cast< void* >( &buffer[ 0 ] ),
buffer.size() * sizeof( WORD ) );
EndUpdateResource( hRes, FALSE );
}
}
However, this is the result after running the code:
The code does add an empty blank line (line 1), this line makes the exe not work correctly, how do I get rid of it?
You need to use std::string instead of std::wstring, as AHK is expecting 8bit characters, not 16bit characters. Also, you need to get rid of your vector, as AHK does not expect each line to be prefixed by its length.
Try this instead:
void ReplaceStringTable() {
HANDLE hRes = BeginUpdateResource( TEXT( "C:\\Users\\CAIO\\Documents\\Github\\main\\scripts\\ahkDebug\\Novo(a) AutoHotkey Script.exe" ), FALSE );
if ( hRes != NULL ) {
std::string data = "MsgBox Test";
UpdateResource( hRes,
RT_RCDATA,
L">AUTOHOTKEY SCRIPT<", //MAKEINTRESOURCE( 1 ),
1033, //MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
const_cast<char*>(data.c_str()),
data.size() );
EndUpdateResource( hRes, FALSE );
}
}
I have a macro, and i use it this way:
int GL = 0;
GL = GetLastError();
DEBUG_MESSAGE( ERR, "RegOpenKeyEx failed. Error code = '%u'. Error description = '%s'", GL, GetErrorText( GL ) );
The function GetErrorText returns a char *, which is the corresponding errortext belonging to the error code.
The problem is, that when i call my macro, it won't call GetErrorText function.
The output will be this : RegOpenKeyEx failed. Error code = '5'. Error description = ''
The Macro is defined this way:
#define DEBUG_MESSAGE( Type, debug_message, ... ) { _debugLog.message( Type, debug_message, ##__VA_ARGS__ ); }
And this is the function what the macro calls:
void log::message( int Type, const char * message, ... )
{
char MessageExpanded[ 2048 ] = { 0 };
va_list args;
int len;
write_indentation();
memset( Message, 0, sizeof( Message ) );
memset( MessageExpanded, 0, sizeof( MessageExpanded ) );
va_start( args, message );
len = _vscprintf( message, args ) + 1; // _vscprintf doesn't count terminating '\0'
vsprintf_s( Message, len, message, args );
va_end( args );
sprintf( MessageExpanded, "%s %s", Spaces, Message );
LOG( MessageExpanded, context.c_str(), "", Type, CurrentFileName );
}//log::message
Is there a way to solve this somehow?
Thanks in advance!
Update:
char * GetErrorText( DWORD dwLastError )
{
DEBUG_METHOD( INFO );
DEBUG_MESSAGE( INFO, "Argument1 = '%d'", dwLastError );
HMODULE hModule = NULL; // default to system source
LPSTR MessageBuffer;
DWORD dwBufferLength;
char Error[ SMALL ] = { 0 };
char * ErrorMsg = NULL;
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
// If dwLastError is in the network range, load the message source.
if ( dwLastError >= NERR_BASE && dwLastError <= MAX_NERR )
{
hModule = LoadLibraryEx( TEXT( "netmsg.dll" ), NULL, LOAD_LIBRARY_AS_DATAFILE );
if ( hModule != NULL ) dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
}
// Call FormatMessage() to allow for message text to be acquired from the system or from the supplied module handle.
if ( dwBufferLength = FormatMessageA(
dwFormatFlags,
hModule, // module to get message from (NULL == system)
dwLastError,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // default language
( LPSTR )&MessageBuffer,
0,
NULL
)
)
{
memset( Error, 0, sizeof( Error ) );
//printf( "\n%s", MessageBuffer );
sprintf( Error, "%s", MessageBuffer );
ErrorMsg = Error;
// Free the buffer allocated by the system.
LocalFree( MessageBuffer );
}
// If we loaded a message source, unload it.
if ( hModule != NULL ) FreeLibrary( hModule );
return ErrorMsg;
}//GetErrorText
GetErrorText() is returning a pointer to a local buffer:
char Error[ SMALL ] = { 0 };
So the pointer it returns is invalid by the time _debugLog.message() is called.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
This error I've managed to solve once more had some problems with the computer and I lost everything.
Could you help me?
I lack only resolve this error, More can not in any way.
------ Build started: Project: Ruby, Configuration: Release Win32 ------
main.cpp
main.cpp(172): error C2660: 'EscanerProcessoMemoria' :
function does not take 0 arguments
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The line :
// main.cpp
#include "StdAfx.h"
#include "MNameColor.h"
#include "MRealHooks.h"
#include "MMrsDecryptor.h"
#include "MInitialCostume.h"
#include "MD5Wrapper.h"
#include "ZGameClient.h"
#include "ZPost.h"
#include "Globais.h"
#include "D3D.h"
#include "MrsCheck.h"
#include "GunzEXP.h"
#include "Hack.h"
#include "HotKeys.h"
#include "Contador.h"
#include "Heuristica.h"
void Exchange1( DWORD Pointer, BYTE Value ){
DWORD Old;
VirtualProtect( (LPVOID)Pointer, 1, PAGE_EXECUTE_READWRITE, &Old );
*(BYTE*)Pointer = Value;
VirtualProtect( (LPVOID)Pointer, 1, Old, &Old );
}
void Exchange2( DWORD Pointer, WORD Value ){
DWORD Old;
VirtualProtect( (LPVOID)Pointer, 2, PAGE_EXECUTE_READWRITE, &Old );
*(WORD*)Pointer = Value;
VirtualProtect( (LPVOID)Pointer, 2, Old, &Old );
}
void Exchange4( DWORD Pointer, DWORD Value ){
DWORD Old;
VirtualProtect( (LPVOID)Pointer, 4, PAGE_EXECUTE_READWRITE, &Old );
*(DWORD*)Pointer = Value;
VirtualProtect( (LPVOID)Pointer, 4, Old, &Old );
}
DWORD ToDword( ... ){
__asm{
mov eax, dword ptr ss:[esp + 4]
retn
}
}
void Apply( void ){
md5wrapper mRunnable;
char szModule[ 256 ];
GetModuleFileName( GetModuleHandle( NULL ), szModule, 256 );
string mPath = string( szModule );
unsigned long Old;
MColor1Detour.Detour( (PBYTE)0x621C00, (PBYTE)GetUserGradeIDColor );
MColor1Detour.Apply();
MColor2Detour.Detour( (PBYTE)0x4A17A0, (PBYTE)GetUserGradeIDColor );
MColor2Detour.Apply();
StageDetour.Detour( (PBYTE)0x44BF40, (PBYTE)StageCreateHandler );
StageDetour.Apply();
ZAppUpdateDetour.Detour( (PBYTE)0x499720, (PBYTE)ZAppOnUpdate, true );
ZAppUpdateDetour.Apply();
SharedTable.Detour( (PBYTE)0x51EAB0, (PBYTE)MAddSharedCommandTable, true );
SharedTable.Apply();
OnRestoreDetour.Detour( (PBYTE)0x4E8DA0, (PBYTE)OnRestore, true );
OnRestoreDetour.Apply();
UpdateCostumes();
//VP
VirtualProtect( (LPVOID)0x6282F8, 15, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (LPVOID)0x6282F8, "Carregando ...\0", 15 );
VirtualProtect( (LPVOID)0x6282F8, 15, Old, &Old );
VirtualProtect( (LPVOID)0x4C7C47, 3, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (LPVOID)0x4C7C47, "\xC2\x10\x00", 3 );
VirtualProtect( (LPVOID)0x4C7C47, 3, Old, &Old );
VirtualProtect( (LPVOID)0x621E1B, 10, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (LPVOID)0x621E1B, "\xEB\x10\xEB\x06\x90\x90\x90\x90\x90\x90", 10 );
VirtualProtect( (LPVOID)0x621E1B, 10, Old, &Old );
VirtualProtect( (LPVOID)0x621E2D, 10, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (LPVOID)0x621E2D, "\x7F\xF6\x83\xEC\x08\xE9\x6C\xA5\xEE\xFF", 10 );
VirtualProtect( (LPVOID)0x621E2D, 10, Old, &Old );
VirtualProtect( (LPVOID)0x4982C1, 3, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (LPVOID)0x4982C1, "\x08\xF7\x0D", 3 );
VirtualProtect( (LPVOID)0x4982C1, 3, Old, &Old );
VirtualProtect( (LPVOID)0x478558, 2, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (PVOID)0x478558, "\xEB\x1B", 2 );
VirtualProtect( (LPVOID)0x478558, 2, Old, &Old );
VirtualProtect( (LPVOID)0x4785F8, 2, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (PVOID)0x4785F8, "\xEB\x07", 2 );
VirtualProtect( (LPVOID)0x4785F8, 2, Old, &Old );
VirtualProtect( (LPVOID)0x4C7202, 2, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (PVOID)0x4C7202, "\xEB", 2 );
VirtualProtect( (LPVOID)0x4C7202, 2, Old, &Old );
VirtualProtect( (LPVOID)0x4A9256, 2, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (PVOID)0x4A9256, "\xEB", 2 );
VirtualProtect( (LPVOID)0x4A9256, 2, Old, &Old );
VirtualProtect( (LPVOID)0x4C6A39, 2, PAGE_EXECUTE_READWRITE, &Old );
memcpy( (PVOID)0x4C6A39, "\xE8\xE2\xD3\xFF\xFF", 2 );
VirtualProtect( (LPVOID)0x4C6A39, 2, Old, &Old );
//End
Exchange4( 0x62F17C, ToDword( &ZGameClient::OnCommand ) );
Exchange4( 0x62B30C, ToDword( &ZCharacter::OnDamaged ) );
Exchange4( 0x62B204, ToDword( &ZMyCharacter::OnDamaged ) );
ExchangeCall( 4728632, ToDword( &ZCharacter::OnDamaged ) );
ApplyHooks( 1 );
Exchange4( 0x4366A2, 8900 );
Exchange2( 0x40830F, 37008 );
Exchange4( 0x40830B, 48955826 );
Exchange1( 0x621CA9, 125 );
Exchange1( 0x45C742, 0 );
Exchange1( 0x4973D8, 56 );
Exchange1( 0x45C27A, 0 );
Exchange4( 0x41A342, 0x800000 );
Exchange4( 0x41AA20, 0x800000 );
Exchange4( 0x41AAB2, 0x800000 );
Exchange4( 0x41B9BA, 0x800000 );
Exchange4( 0x41C2EE, 0x800000 );
Exchange4( 0x43908A, 0x800000 );
Exchange4( 0x4C4B95, 0x800000 );
ExchangeReplaceCall( 0x42AF40, (unsigned long)&ZPostChannelChat );
ExchangeReplaceCall( 0x481170, (unsigned long)&ZPostSkill );
ExchangeReplaceCall( 0x42ADC0, (unsigned long)&ZPostPeerChat );
pGunz = (unsigned char*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 2231296 );
if( pGunz ){
for( int n = 0; n < 2231296; n++ ){
pGunz[ n ] = *(unsigned char*)(n + 4198400);
}
}
}
void Escaners(){
EscanerProcessoMemoria();
EscanerProcessoSistema();
}
int __stdcall DllMain( HMODULE hModule, DWORD dwReason, LPVOID lpParam ){
DisableThreadLibraryCalls( hModule );
EscondeProtecao( hModule );
if( dwReason == DLL_PROCESS_ATTACH ){
Apply( );
CheckFiles();
ContarArquivos();
VerificarHack();
CreateThread (0,0,(LPTHREAD_START_ROUTINE)GunzEXP,0,0,0);
CreateThread (0,0,(LPTHREAD_START_ROUTINE)ChecarHotKeys,0,0,0);
CreateThread (0,0,(LPTHREAD_START_ROUTINE)Escaners,0,0,0);
CreateThread (0,0,(LPTHREAD_START_ROUTINE)TxtCheckWindow,0,0,0);
}
return true;
}
Please Help me
Check the declaration of EscanerProcessoMemoria(), and ensure it takes 0 arguments. If not, make sure you include any headers that might have potentially overloaded this function with 0 arguments.
Other than that, the compiler is pretty much giving you the answer. Bottom line: Check the documentation of EscanerProcessoMemoria()...if there is any.
Due to the new usage for returning the process id? And how can i check when memory is begin leaked, throughtout debugging my application? (This length check on the explanation section really sucks =P)
#include "stdafx.h"
#include "Process.h"
#include <TlHelp32.h>
#include <iostream>
DWORD GetProcessId( const wchar_t* szProcess )
{
if( szProcess )
{
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
PROCESSENTRY32 *pe32 = new PROCESSENTRY32();
memset( pe32, 0, sizeof( PROCESSENTRY32 ) );
pe32->dwSize = sizeof( PROCESSENTRY32 );
//Process32First( hSnapshot, pe32 );
while( Process32Next( hSnapshot, pe32 ) )
{
if( pe32->szExeFile && !wcscmp( szProcess, pe32->szExeFile ) )
{
CloseHandle( hSnapshot );
return( pe32->th32ProcessID ); // std::wcout << pe32->szExeFile << std::endl;
}
}
CloseHandle( hSnapshot );
}
return 0;
}
HANDLE GetProcessHandle( DWORD dwProcessId )
{
if( dwProcessId )
return( OpenProcess( PROCESS_VM_READ | PROCESS_VM_WRITE, 0, dwProcessId ) );
return 0;
}
bool WriteExternProcessMemory( HANDLE hProcess, void* pAddr, size_t uSize, const char* szWrite, LPCVOID outBuffer )
{
if( pAddr && szWrite && hProcess )
{
DWORD dwOldProtect;
if( !VirtualProtectEx( hProcess, pAddr, uSize, PAGE_EXECUTE_READWRITE, &dwOldProtect ) )
return( !WriteProcessMemory( hProcess, pAddr, outBuffer, uSize, NULL ) );
}
return false;
}
-Edit,
the usage is:
void *pRecv;
WriteExternProcessMemory( GetProcessHandle( GetProcessId( _T( "notepad.exe" ) ) ), (void*)0x401000, 2, "\x40\x40", &pRecv );
This is leaking:
PROCESSENTRY32 *pe32 = new PROCESSENTRY32();
Better use:
PROCESSENTRY32 pe32 = {0};
pe32.dwSize = sizeof( PROCESSENTRY32 );
//Process32First( hSnapshot, pe32 );
while( Process32Next( hSnapshot, &pe32 ) )
...
Also, you're not closing the handle created at GetProcessHandle, which is also a leak.
Yes, you are right. Allocating memory without freeing it later, as your program does, constitutes a memory leak.
You can find leaks in your program by using a memory leak detector.
Valgrind is a wonderful tool to tell you about memory leaks. If you are compiling with debugging symbols (-g for GCC), it will even tell you what line the leak happened on!
http://valgrind.org/
I have the following piece of code. This is written for getting the list of timezones from registry and populating into an array. This piece of code works fine in Win7 and Vista OS but not in WinXp and Win2k3.
The reason is because of the size of array getting overflown. I have defined only 100 elements. However there are more than 100 elements in the registry.
Now my question is why this does not fail in Vista or Win7 machines. Is there any difference in allocation of memory between Xp and Vista OS.
It crashes in the line while getting 100the element from registry
while( RegEnumKeyEx( Key, nTimezones, tzKeyNames[nTimezones].GetBuffer( size ), &size, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS )
Full code
CString sRegKey;
HKEY Key;
HKEY subKey;
int nTimezones = 0;
CArray< CString, CString > tzKeyNames;
tzOffset.SetSize( 100, 10 );
tzKeyNames.SetSize( 100, 10 );
tzDisplayNames.SetSize( 100, 10 );
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
GetVersionEx(&osvi);
if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
sRegKey = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones");
}
else
{
sRegKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones");
}
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, sRegKey, 0, KEY_READ , &Key ) == ERROR_SUCCESS )
{
DWORD size;
DWORD type = REG_SZ;
TZINFO tz;
_TCHAR name[ 128 ];
BYTE data[ 128 ];
size = 128;
while( RegEnumKeyEx( Key, nTimezones, tzKeyNames[nTimezones].GetBuffer( size ), &size, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS )
{
tzKeyNames[nTimezones].ReleaseBuffer();
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, sRegKey + _T("\\") + (LPCTSTR)tzKeyNames[nTimezones], 0, KEY_READ , &subKey ) == ERROR_SUCCESS )
{
size = 128;
if( RegQueryValueEx( subKey, _T("Display"), NULL, &type, (unsigned char*)name, &size ) == ERROR_SUCCESS )
{
tzDisplayNames[nTimezones] = name;
}
size = 128;
if( RegQueryValueEx( subKey, _T("TZI"), NULL, &type, data, &size ) == ERROR_SUCCESS )
{
memcpy( &tz, data, size );
tzOffset[ nTimezones ] = (int)(( tz.Bias / -60.0 ) * 2.0 ) + 24;
}
RegCloseKey( subKey );
}
nTimezones++;
}
RegCloseKey( Key );
}
Exception is raised when application tries to read/write a piece of memory that is not in it's address space. In one case after the array there was addressed memory, in other there wasn't. This is random. And yes, various allocation algorithm will lead to various results but this is only one element causing randomness. The results are also dependent on how many bytes are allocated and where they are allocated by your application, other applications and the OS itself.
// EDIT
tzKeyNames[nTimezones].ReleaseBuffer();
Probably the problem is not in reading after the array's end (it's usually within addressed space) but that some garbage was read. This garbage is used as a pointer, when dereferenced causes exception.