ich hatte mir vorgenommen mit Python unter Windows zu experimentieren und hatte aus vergangener Zeit ein altes C++ Schnipsel gefunden welches nun von mir nach Python übersetzt werden wollte.
Das ganze soll ein Spiel suspended starten, eine Multiplayer DLL laden und das Spiel darauf weiter ausführen.
[codebox=cpp file=Unbenannt.cpp]#include <windows.h>
#include <cstring>
// The purpose of this program is just to show the basics of a custom launcher that people can make in SA-MP.
#include <iostream>
#include <stdio.h>
#include <direct.h>
// entry point
int main(int argc, char* argv[])
{
// Prepare to create a new process.
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo;
memset(&ProcessInfo, 0, sizeof(PROCESS_INFORMATION));
memset(&StartupInfo, 0, sizeof(STARTUPINFO));
char *cwpath = NULL;
cwpath = getcwd(NULL, 0); // or _getcwd
if ( cwpath != NULL)
printf("%s\n", cwpath);
// Tell the user to enter an IP.
std::cout << "Please enter the IP you would like to connect to.\n";
// Get the IP.
char ip[24];
std::cin >> ip;
// Tell the user to enter a port
std::cout << "Please enter the port.\n";
// Get the port they typed.
int port;
std::cin >> port;
// Get the user's gta_sa location
char exeLocation[256], name[24];
DWORD buffer = sizeof(exeLocation);
// Open registry key
HKEY hKey;
long lError = RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\SAMP",
0,
KEY_READ,
&hKey);
// Get value
DWORD dwRet = RegQueryValueEx(hKey, "gta_sa_exe", NULL, NULL, (LPBYTE)&exeLocation, &buffer);
// Make sure we got a good value for the gta_sa path
if (dwRet != ERROR_SUCCESS)
{
MessageBoxA(NULL, "Could not get the location of your GTA:SA installation. Is SA-MP installed correctly?", "SA:MP Launcher", MB_ICONERROR);
return 0;
}
// remove \gta_sa.exe in a new variable (leaving just the directory path)
char path[256];
//strcpy(path, sizeof(path), exeLocation);
strcpy(path, exeLocation);
path[strlen(path) - 11] = '\0';
// Get the player name
buffer = sizeof(name);
dwRet = RegQueryValueEx(hKey, "PlayerName", NULL, NULL, (LPBYTE)&name, &buffer);
// Close registry
RegCloseKey(hKey);
char commandLine[128];
if (dwRet != ERROR_SUCCESS)
{
// Since a name couldn't be found, ask for one.
std::cout << "Enter a name";
std::cin >> name;
}
// Construct it all in one command line string.
//sprintf(commandLine, sizeof(commandLine), "-c -h %s -p %d -n %s", ip, port, name);
sprintf(commandLine, "-c -h %s -p %d -n %s", ip, port, name);
// Create a new process, but don't let it run yet, it's suspended.
if (CreateProcess(exeLocation, commandLine, NULL, NULL, FALSE, DETACHED_PROCESS | CREATE_SUSPENDED, NULL, path, &StartupInfo, &ProcessInfo))
{
// Create a new string that will hold the path to the file samp.dll
char szWithSampdll[256] = "";
//sprintf(szWithSampdll, sizeof(szWithSampdll), "%s\\samp.dll", path);
sprintf(szWithSampdll, "%s\\samp.dll", path);
// Get the module handle to kernal32.dll
HMODULE hMod = GetModuleHandle("kernel32.dll");
// Create address variable to hold the address of the LoadLibrary function.
void* addr = NULL;
// If it was a valid handle.
if (hMod)
// Get the address of the LoadLibrary function so we can load samp.dll
addr = (void*)GetProcAddress(hMod, "LoadLibraryA");
else
{
MessageBoxA(NULL, "Could not find kernel32.dll", "SA:MP Launcher", MB_ICONERROR);
return 0;
}
// Allocate memory in the new process we just created to store the string of the samp.dll file path.
void* arg = (void*)VirtualAllocEx(ProcessInfo.hProcess, NULL, strlen(szWithSampdll), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
// Make sure the space was allocated.
if (arg != NULL)
// Write to the memory we just allocated the file path to samp.dll including directory.
WriteProcessMemory(ProcessInfo.hProcess, arg, szWithSampdll, strlen(szWithSampdll), NULL);
else
{
// arg is null, and we can't continue then.
// Let the user know there was a problem and exit.
MessageBoxA(NULL, "Memory could not be allocated to inject samp.dll", "SA:MP Launcher", MB_ICONERROR);
return 0;
}
// Create new handle to our remote thread.
HANDLE id = NULL;
// Make sure The address of LoadLibrary isn't NULL
if (addr != NULL)
{
// Create a remote thread that calls LoadLibrary, and as the parameter, the memory location we just wrote the samp.dll path to.
// also don't execute this thread, but just create.
id = CreateRemoteThread(ProcessInfo.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, CREATE_SUSPENDED, NULL);
}
else
{
MessageBoxA(NULL, "Could not find the address of LoadLibraryA", "SA:MP Launcher", MB_ICONERROR);
return 0;
}
// Make sure id is a valid handle
if (id)
{
// Resume the remote thread.
ResumeThread(id);
std::cout << "...patience..." << std::endl;
// Wait for the remote thread to finish executing.
WaitForSingleObject(id, INFINITE);
}
else
{
MessageBoxA(NULL, "the ID returned from CreateRemoteThread was invalid.", "SA:MP Launcher", MB_ICONERROR);
return 0;
}
// Free the memory we just allocated that stores the samp.dll file path since LoadLibrary has been called and it's not needed anymore.
VirtualFreeEx(ProcessInfo.hProcess, arg, 0, MEM_RELEASE);
// Resume the process (It was suspended, remember?)
ResumeThread(ProcessInfo.hThread);
// Close the handle to the process we created.
CloseHandle(ProcessInfo.hProcess);
}
// Done!
return 0;
}
[/code]
Nun habe ich angefangen es umzusetzen und habe folgendes zusammengebracht:
Code: Alles auswählen
from _winreg import *
import time
import ctypes
import sys
from ctypes import *
from subprocess import Popen
from ctypes import wintypes
from _ctypes import call_function
import win32process
import win32con
import win32event
import win32api
SERVER_IP = '127.0.0.1'
SERVER_PORT = '7777'
gta_path = 'C:\Program Files (x86)\Rockstar Games\GTA San Andreas\\'
registry = ConnectRegistry(None, HKEY_CURRENT_USER)
sampRegistryKey = OpenKey(registry, 'SOFTWARE\SAMP\\')
name = QueryValueEx(sampRegistryKey, 'playerName')[0]
command = '-c -n %s -h %s -p %s' % (name, SERVER_IP, SERVER_PORT)
si = win32process.STARTUPINFO()
(hProcess, hThread, dwProcessId, dwThreadId) = win32process.CreateProcess('%sgta_sa.exe' % gta_path, command, None, None, False, win32con.DETACHED_PROCESS | win32con.CREATE_SUSPENDED, None, gta_path, si)
print '[*] PID: %s' % dwProcessId
kernel32 = windll.kernel32
kernel32.LoadLibraryA.restype = c_void_p
kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
kernel32.GetProcAddress.restype = c_void_p
hMod = kernel32.LoadLibraryA(b"kernel32")
if not hMod:
print '[!] hMod not loaded'
raise SystemExit
else:
print '[*] hMod loaded'
addr = kernel32.GetProcAddress(hMod, b"LoadLibraryA")
if addr == 0:
print '[!] Could not get LoadLibraryA addr'
raise SystemExit
else:
print '[*] LoadLibraryA addr found'
dll_path = 'C:\Program Files (x86)\Rockstar Games\GTA San Andreas\samp.dll'
dll_len = len(dll_path)
arg = kernel32.VirtualAllocEx(int(hProcess), 0, dll_len, win32con.MEM_RESERVE | win32con.MEM_COMMIT, win32con.PAGE_READWRITE)
if not arg:
print '[!] Could not allocate memory'
raise SystemExit
else:
print '[*] Memory allocated'
written = c_int(0)
kernel32.WriteProcessMemory(int(hProcess), arg, dll_path, len(dll_path), byref(written))
thread_id = c_ulong(0)
thread = kernel32.CreateRemoteThread(int(hProcess), 0, 0, c_long(addr), arg, win32con.CREATE_SUSPENDED, thread_id)
if not thread:
print '[!] Could not create remote thread'
raise SystemExit
else:
print '[*] Thread created'
kernel32.ResumeThread(thread)
print 'waiting...'
win32event.WaitForSingleObject(thread, win32event.INFINITE)
print 'finished'
kernel32.VirtualFreeEx(int(hProcess), arg, 0, win32con.MEM_RELEASE)
kernel32.ResumeThread(int(hThread))
hProcess.Close()
Die C++ Variante läuft einwandfrei.
Habe ich hier etwas übersehen?
Danke im voraus.