FAQ/Hook/SQLiteDB.cpp

272 lines
6.7 KiB
C++

#include "pch.h"
#include "SQLiteDB.h"
#include "Mutex.h"
#include <set>
#include <grpcpp/grpcpp.h>
#include "ModuleHook.h"
#include "SQLiteQuery.h"
#include "SQLRpc.h"
#include "Utils.h"
int SQLite3DB_execDML(void* self, const char* sql, int* error);
decltype(SQLite3DB_execDML)* OriginalSQLite3DB_execDML = nullptr;
int SQLite3DB_execQueryEx(void *self, int a2, char *sql, int *errOut, int a5);
decltype(SQLite3DB_execQueryEx)* OriginalSQLite3DB_execQueryEx = nullptr;
int SQLite3DB_open(void* self, const char *filename);
decltype(SQLite3DB_open)* OriginalSQLite3DB_open;
void SQLite3DB_key(void* self, const void *key, int a3);
decltype(SQLite3DB_key)* OriginalSQLite3DB_key;
void SQLite3DB_rekey(void* self, const void *key, int a3);
decltype(SQLite3DB_rekey)* OriginalSQLite3DB_rekey;
void SQLite3DB_execQuery(void* self, int a2, char *sql, int *a4);
decltype(SQLite3DB_execQuery)* OriginalSQLite3DB_execQuery;
const char* SQLite3DB_db_filename(void* self, const char* dbName);
decltype(SQLite3DB_db_filename)* OriginalSQLite3DB_db_filename;
void SQLite3DB_close(void* self);
decltype(SQLite3DB_close)* OriginalSQLite3DB_close;
static Mutex<std::set<void*>> SQLite3DBPointers = Mutex<std::set<void*>>(std::set<void*>());
static Mutex<bool> MsgDBFound = Mutex<bool>(false);
static std::unique_ptr<Mutex<bool>> DBLock = std::make_unique<Mutex<bool>>(false);
void setupShell(HookSQLite3DB* db);
void HookSQLite3DB::initHook(ModuleHook& hook)
{
hook.begin();
auto fn = &HookSQLite3DB::execDML;
hook.hookFunc("SQLite3DB::execDML",
"?execDML@CppSQLite3DB@@QAEHPBDPAH@Z",
(void**)&OriginalSQLite3DB_execDML,
(void*&)fn);
auto fn2 = &HookSQLite3DB::execQueryEx;
hook.hookFunc("SQLite3DB::execQueryEx",
"?execQueryEx@CppSQLite3DB@@QAE?AVCppSQLite3Query@@PBDPAHH@Z",
(void**)&OriginalSQLite3DB_execQueryEx,
(void*&)fn2);
auto fexecQuery = &HookSQLite3DB::execQuery;
hook.hookFunc("SQLite3DB::execQuery",
"?execQuery@CppSQLite3DB@@QAE?AVCppSQLite3Query@@PBDPAH@Z",
(void**)&OriginalSQLite3DB_execQuery,
(void*&)fexecQuery);
auto fn3 = &HookSQLite3DB::open;
hook.hookFunc("SQLite3DB::open",
"?open@CppSQLite3DB@@QAEHPBD@Z",
(void**)&OriginalSQLite3DB_open,
(void*&)fn3);
auto fkey = &HookSQLite3DB::key;
hook.hookFunc("SQLite3DB::key",
"?key@CppSQLite3DB@@QAEXPBXH@Z",
(void**)&OriginalSQLite3DB_key,
(void*&)fkey);
auto frekey = &HookSQLite3DB::rekey;
hook.hookFunc("SQLite3DB::rekey",
"?rekey@CppSQLite3DB@@QAEXPBXH@Z",
(void**)&OriginalSQLite3DB_rekey,
(void*&)frekey);
auto dbName = &HookSQLite3DB::db_filename;
hook.hookFunc("SQLite3DB::db_name",
"?db_filename@CppSQLite3DB@@QAEPBDPBD@Z",
(void**)&OriginalSQLite3DB_db_filename,
(void*&)dbName);
auto close = &HookSQLite3DB::close;
hook.hookFunc("SQLite3DB::close",
"?close@CppSQLite3DB@@QAEXXZ",
(void**)&OriginalSQLite3DB_close,
(void*&)close);
hook.commit();
}
int HookSQLite3DB::execDML(const char* sql, int* error)
{
// logFmt("Call to execDML %s", sql);
if(DBLock)
DBLock->lock();
int result;
__asm {
mov eax, error
push eax
mov eax, sql
push eax
mov ecx, this
call OriginalSQLite3DB_execDML
mov result, eax
};
return result;
}
int HookSQLite3DB::execQueryEx(int a2, char* sql, int* a4, int a5)
{
if(DBLock)
DBLock->lock();
// logFmt("Call to execQueryEx %s", sql);
int result;
__asm {
mov eax, a5
push eax
mov eax, a4
push eax
mov eax, sql
push eax
mov eax, a2
push eax
mov ecx, this
call OriginalSQLite3DB_execQueryEx
mov result, eax
};
return result;
}
__declspec(dllexport) int HookSQLite3DB::execQuery(void* query, const char* sql, int* errOut)
{
if(DBLock)
DBLock->lock();
// logFmt("Call to execQuery %s", sql);
bool dbFound = false;
{
auto guard = MsgDBFound.lock();
if(!*guard)
{
auto filename = this->db_filename("main");
auto basename = Utils::PathBaseName(std::string(filename));
logFmt("db_filename: %s", basename.c_str());
if (basename == "Msg3.0.db")
{
logFmt("Got Msg3.0.db");
*guard = true;
dbFound = true;
}
}
}
if(dbFound)
setupShell(this);
int result;
__asm {
mov eax, errOut
push eax
mov eax, sql
push eax
mov eax, query
push eax
mov ecx, this
call OriginalSQLite3DB_execQuery
mov result, eax
};
return result;
}
const char* HookSQLite3DB::db_filename(const char* dbName)
{
if(DBLock)
DBLock->lock();
const char* result;
__asm {
push dbName
mov ecx, this
call OriginalSQLite3DB_db_filename
mov result, eax
}
return result;
}
int HookSQLite3DB::open(const char* filename)
{
if(DBLock)
DBLock->lock();
int result;
__asm {
mov eax, filename
push eax
mov ecx, this
call OriginalSQLite3DB_open
mov result, eax
};
return result;
}
void HookSQLite3DB::key(const void* key, int a3)
{
if(DBLock)
DBLock->lock();
logFmt("Call to key %p %x", key, a3);
__asm {
mov eax, a3
push eax
mov eax, key
push eax
mov ecx, this
call OriginalSQLite3DB_key
}
}
void HookSQLite3DB::rekey(const void* key, int a3)
{
if(DBLock)
DBLock->lock();
logFmt("Call to rekey %p %x", key, a3);
__asm {
mov eax, a3
push eax
mov eax, key
push eax
mov ecx, this
call OriginalSQLite3DB_rekey
}
}
void HookSQLite3DB::close()
{
auto filename = this->db_filename("main");
auto basename = Utils::PathBaseName(std::string(filename));
if(basename == "Msg3.0.db")
{
logFmt("Attempt to close msg db.");
DBLock->lock();
}
__asm {
mov ecx, this
call OriginalSQLite3DB_close
}
}
void setupShell(HookSQLite3DB* db)
{
auto guard = DBLock->lock();
SQLRpc service(db);
logFmt("server start on 0.0.0.0:47382");
service.serve();
logFmt("Server down");
}