123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #include <WinSock2.h>
- #pragma comment(lib, "Ws2_32.lib")
- #include <detours.h>
- #include <thread>
- #include <string>
- #include "framework.h"
- #include "PluginConfigApi.h"
- #include <iostream>
- bool(__cdecl* DSC_EXECUTE_COMMAND)(__int64 dsc_address, float delta_time, __int64 start_time, void* wait_timer, int* a5, int a6, int a7)
- = (bool(__cdecl*)(__int64 dsc_address, float delta_time, __int64 start_time, void* wait_timer, int* a5, int a6, int a7))
- 0x14011CBA0;
- bool hookedDSC_EXECUTE_COMMAND(__int64 dsc_address, float delta_time, __int64 start_time, void* wait_timer, int* a5, int a6, int a7);
- void serve();
- bool debug = false;
- unsigned short port = 8139;
- void loadConfig()
- {
- port = GetPrivateProfileIntW(L"general", L"port", 8139, CONFIG_FILE);
- debug = GetPrivateProfileIntW(L"general", L"debug", 0, CONFIG_FILE) > 0;
- return;
- }
- float last_delta_time = 0.0;
- __int64 last_start_time = 0i64;
- void* last_wait_timer = nullptr;
- int* last_a5 = nullptr;
- int last_a6 = 0;
- int last_a7 = 0;
- bool hookedDSC_EXECUTE_COMMAND(__int64 dsc_address, float delta_time, __int64 start_time, void* wait_timer, int* a5, int a6, int a7)
- {
- last_delta_time = delta_time;
- last_start_time = start_time;
- last_wait_timer = wait_timer;
- last_a5 = a5;
- last_a6 = a6;
- last_a7 = a7;
- return DSC_EXECUTE_COMMAND(dsc_address, delta_time, start_time, wait_timer, a5, a6, a7);
- }
- void serve()
- {
- using namespace std;
- cout << "[DSCRemote] Staring server..." << endl;
- WSADATA wsadata;
- int result = WSAStartup(MAKEWORD(2, 2), &wsadata);
- if (result) // error
- {
- cout << "[DSCRemote] E: WSAStartup error " << result << '.' << endl;
- return;
- }
- SOCKET sock;
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (result == INVALID_SOCKET)
- {
- cout << "[DSCRemote] E: Invalid socket." << endl;
- WSACleanup();
- return;
- }
- sockaddr_in saddrin;
- saddrin.sin_family = AF_INET;
- saddrin.sin_addr.s_addr = 0;
- saddrin.sin_port = htons(port);
- result = ::bind(sock, (sockaddr*)&saddrin, sizeof(sockaddr_in));
- if (result) // error
- {
- cout << "[DSCRemote] E: Couldn't bind port " << port << '.' << endl;
- closesocket(sock);
- WSACleanup();
- return;
- }
- result = listen(sock, 1);
- if (result) // error
- {
- cout << "[DSCRemote] E: Couldn't listen." << endl;
- closesocket(sock);
- WSACleanup();
- return;
- }
- while (true)
- {
- cout << "[DSCRemote] Waiting for client..." << endl;
- SOCKET client_sock;
- client_sock = accept(sock, NULL, NULL);
- cout << "[DSCRemote] Client accepted." << endl;
- char buff_recv[64];
- vector<int> cmdStack;
- do
- {
- result = recv(client_sock, buff_recv, sizeof(buff_recv), 0);
- if (result > 0)
- {
- if (debug) cout << "[DSCRemote] D: Received: " << buff_recv << endl;
- if (buff_recv[0] != 'i')
- {
- long stack = stol(buff_recv);
- for (int i = 0; i < sizeof(buff_recv); i++) buff_recv[i] = '\0';
- cmdStack.push_back(stack);
- const char buff_out[] = "Stacking command/parameter. Send 'i' to inject.";
- send(client_sock, buff_out, sizeof(buff_out), 0);
- continue;
- }
- for (int i = 0; i < sizeof(buff_recv); i++) buff_recv[i] = '\0';
- const char buff_out[] = "Injecting stack.";
- send(client_sock, buff_out, sizeof(buff_out), 0);
- const int64_t dscbaseaddr = 0x140CDD978i64;
- int* currentpos = (int*)(dscbaseaddr + 0x2bf2c);
- int* command = (int*)(dscbaseaddr + 0xc);
- int posbk = *currentpos;
- vector<int> cmdbk;
- for (int i=0; i<cmdStack.size(); i++)
- cmdbk.push_back(command[i]);
- *currentpos = 0;
- for (int i = 0; i < cmdStack.size(); i++)
- {
- if (debug) cout << "[DSCRemote] D: Injecting " << cmdStack.at(i) << endl;
- command[i] = cmdStack.at(i);
- }
- cmdStack.clear();
- DSC_EXECUTE_COMMAND(dscbaseaddr, last_delta_time, last_start_time, last_wait_timer, last_a5, last_a6, last_a7);
- for (int i = 0; i < cmdbk.size(); i++)
- {
- if (debug) cout << "[DSCRemote] D: Restoring " << cmdbk.at(i) << endl;
- command[i] = cmdbk.at(i);
- }
-
- cmdbk.clear();
- *currentpos = posbk;
- }
- } while (result > 0);
- closesocket(client_sock);
- cout << "[DSCRemote] Restarting..." << endl;
- }
- cout << "[DSCRemote] Bye!" << endl;
- closesocket(sock);
- WSACleanup();
- }
- BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
- {
- if (ul_reason_for_call == DLL_PROCESS_ATTACH)
- {
- using namespace std;
- loadConfig();
- DisableThreadLibraryCalls(hModule);
- DetourTransactionBegin();
- DetourUpdateThread(GetCurrentThread());
- cout << "[DSCRemote] Hooking functions..." << endl;
- DetourAttach(&(PVOID&)DSC_EXECUTE_COMMAND, (PVOID)hookedDSC_EXECUTE_COMMAND);
- cout << "[DSCRemote] Functions hooked." << endl;
- DetourTransactionCommit();
- thread* server_thread = new thread(serve);
- }
- return TRUE;
- }
- PluginConfig::PluginConfigOption config[] = {
- { PluginConfig::CONFIG_NUMERIC, new PluginConfig::PluginConfigNumericData{ L"port", L"general", CONFIG_FILE, L"Port", L"TCP/IP port.", 8139, 1, USHRT_MAX } },
- { PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"debug", L"general", CONFIG_FILE, L"Debug", L"Print extra information.", false } },
- };
- extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
- {
- return L"DSCRemote";
- }
- extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
- {
- return L"Allows external applications to send DSC commands via TCP/IP.";
- }
- extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void)
- {
- return PluginConfig::PluginConfigArray{ _countof(config), config };
- }
|