-
Notifications
You must be signed in to change notification settings - Fork 1
/
samp_launcher.cpp
161 lines (127 loc) · 4.77 KB
/
samp_launcher.cpp
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
#include <windows.h>
// The purpose of this program is just to show the basics of a custom launcher that people can make in SA-MP.
#include <iostream>
// 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));
// 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_s(path, sizeof(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_s(commandLine, sizeof(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_s(szWithSampdll, sizeof(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;
}