mirror of
https://github.com/UzixLS/KernelEx.git
synced 2025-07-18 23:11:19 +03:00
import KernelEx-4.0-Final2
This commit is contained in:
@ -40,7 +40,15 @@ DebugWindow::DebugWindow()
|
||||
{
|
||||
DWORD tid;
|
||||
hwnd = (HWND) -1;
|
||||
|
||||
//we're interested in everything
|
||||
includes.push_back("*");
|
||||
//these usually aren't interesting
|
||||
excludes.push_back("Tls");
|
||||
excludes.push_back("Heap");
|
||||
excludes.push_back("CriticalSection");
|
||||
excludes.push_back("Interlocked");
|
||||
|
||||
InitializeCriticalSection(&cs);
|
||||
InitCommonControls();
|
||||
hThread = CreateThread(NULL, 0, thread, (void*) this, 0, &tid);
|
||||
@ -79,11 +87,21 @@ BOOL CALLBACK DebugWindow::DebugDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
nmhdr = (NMHDR*) lParam;
|
||||
if (nmhdr->idFrom == IDC_LOG && nmhdr->code == NM_RCLICK)
|
||||
{
|
||||
_this->HandleMenu();
|
||||
break;
|
||||
}
|
||||
if (nmhdr->idFrom == IDC_LOG)
|
||||
if (nmhdr->code == NM_RCLICK)
|
||||
{
|
||||
_this->HandleMenu();
|
||||
break;
|
||||
}
|
||||
else if (nmhdr->code == LVN_KEYDOWN)
|
||||
{
|
||||
LPNMLVKEYDOWN nm = (LPNMLVKEYDOWN) lParam;
|
||||
if (nm->wVKey == VK_DELETE)
|
||||
{
|
||||
_this->DeleteSelItems();
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@ -94,7 +112,7 @@ void DebugWindow::InitDialog(HWND hwnd)
|
||||
{
|
||||
hList = GetDlgItem(hwnd, IDC_LOG);
|
||||
SetClassLong(hwnd, GCL_STYLE, GetClassLong(hwnd, GCL_STYLE) | CS_NOCLOSE);
|
||||
MoveWindow(hwnd, 0, 0, 320, 200, TRUE);
|
||||
MoveWindow(hwnd, 0, 0, 480, 200, TRUE);
|
||||
SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE,
|
||||
0, LVS_EX_FULLROWSELECT);
|
||||
|
||||
@ -102,27 +120,29 @@ void DebugWindow::InitDialog(HWND hwnd)
|
||||
memset(&col, 0, sizeof(col));
|
||||
col.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
|
||||
|
||||
col.cx = 80;
|
||||
col.pszText = "Process";
|
||||
col.cx = 20;
|
||||
col.pszText = "Depth";
|
||||
ListView_InsertColumn(hList, 0, &col);
|
||||
col.cx = 60;
|
||||
col.pszText = "Thread";
|
||||
ListView_InsertColumn(hList, 1, &col);
|
||||
col.cx = 80;
|
||||
col.cx = 90;
|
||||
col.pszText = "Source";
|
||||
ListView_InsertColumn(hList, 2, &col);
|
||||
col.cx = 80;
|
||||
col.cx = 90;
|
||||
col.pszText = "Dest";
|
||||
ListView_InsertColumn(hList, 3, &col);
|
||||
col.cx = 120;
|
||||
col.cx = 130;
|
||||
col.pszText = "Function";
|
||||
ListView_InsertColumn(hList, 4, &col);
|
||||
col.cx = 40;
|
||||
col.cx = 60;
|
||||
col.mask |= LVCF_FMT;
|
||||
col.fmt = LVCFMT_RIGHT;
|
||||
col.pszText = "Return";
|
||||
ListView_InsertColumn(hList, 5, &col);
|
||||
|
||||
#define NUM_COLS 6
|
||||
|
||||
menu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_LOGMENU));
|
||||
menu = GetSubMenu(menu, 0);
|
||||
}
|
||||
@ -151,6 +171,18 @@ void DebugWindow::HandleMenu()
|
||||
}
|
||||
}
|
||||
|
||||
void DebugWindow::DeleteSelItems()
|
||||
{
|
||||
if (ListView_GetSelectedCount(hList) == 0)
|
||||
return;
|
||||
|
||||
for (int i = ListView_GetItemCount(hList) - 1 ; i >= 0 ; i--)
|
||||
{
|
||||
if (ListView_GetItemState(hList, i, LVIS_SELECTED))
|
||||
ListView_DeleteItem(hList, i);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugWindow::AppendLog(char* msg)
|
||||
{
|
||||
LV_ITEM item;
|
||||
@ -232,9 +264,9 @@ BOOL CALLBACK DebugWindow::FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPA
|
||||
len1 = GetWindowTextLength(GetDlgItem(hwnd, IDC_DFINCLUDE)) + 1;
|
||||
len2 = GetWindowTextLength(GetDlgItem(hwnd, IDC_DFEXCLUDE)) + 1;
|
||||
buf = (char*) alloca(max(len1, len2));
|
||||
EnterCriticalSection(&_this->cs);
|
||||
|
||||
GetDlgItemText(hwnd, IDC_DFINCLUDE, buf, len1);
|
||||
EnterCriticalSection(&_this->cs);
|
||||
_this->includes.clear();
|
||||
pch = strtok_r(buf, ";", &p);
|
||||
if (pch)
|
||||
@ -243,8 +275,10 @@ BOOL CALLBACK DebugWindow::FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPA
|
||||
while ((pch = strtok_r(NULL, ";", &p)) != NULL)
|
||||
_this->includes.push_back(pch);
|
||||
}
|
||||
LeaveCriticalSection(&_this->cs);
|
||||
|
||||
GetDlgItemText(hwnd, IDC_DFEXCLUDE, buf, len2);
|
||||
EnterCriticalSection(&_this->cs);
|
||||
_this->excludes.clear();
|
||||
pch = strtok_r(buf, ";", &p);
|
||||
if (pch)
|
||||
@ -253,8 +287,8 @@ BOOL CALLBACK DebugWindow::FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPA
|
||||
while ((pch = strtok_r(NULL, ";", &p)) != NULL)
|
||||
_this->excludes.push_back(pch);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&_this->cs);
|
||||
|
||||
EndDialog(hwnd, 0);
|
||||
break;
|
||||
}
|
||||
@ -312,7 +346,7 @@ void DebugWindow::WriteToFile()
|
||||
col.pszText = buf;
|
||||
col.cchTextMax = sizeof(buf);
|
||||
DWORD wlen;
|
||||
for (int j = 0 ; j < 6 ; j++)
|
||||
for (int j = 0 ; j < NUM_COLS ; j++)
|
||||
{
|
||||
DWORD len;
|
||||
ListView_GetColumn(hList, j, &col);
|
||||
@ -326,7 +360,7 @@ void DebugWindow::WriteToFile()
|
||||
rows = ListView_GetItemCount(hList);
|
||||
for (int i = 0 ; i < rows ; i++)
|
||||
{
|
||||
for (int j = 0 ; j < 6 ; j++)
|
||||
for (int j = 0 ; j < NUM_COLS ; j++)
|
||||
{
|
||||
DWORD len; DWORD wlen;
|
||||
ListView_GetItemText(hList, i, j, buf, sizeof(buf));
|
||||
@ -361,7 +395,6 @@ void DebugWindow::append(const char* str)
|
||||
{
|
||||
static char msg[DEBUGMSG_MAXLEN];
|
||||
bool filter_out = true;
|
||||
list<sstring>::const_iterator it;
|
||||
|
||||
EnterCriticalSection(&cs);
|
||||
|
||||
@ -370,21 +403,28 @@ void DebugWindow::append(const char* str)
|
||||
{
|
||||
if (includes.size() == 1 && strcmp(includes.front(), "*") == 0)
|
||||
filter_out = false;
|
||||
else for (it = includes.begin() ; it != includes.end() ; it++)
|
||||
if (strstr(str, *it))
|
||||
{
|
||||
filter_out = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
list<sstring>::const_iterator it;
|
||||
for (it = includes.begin() ; it != includes.end() ; it++)
|
||||
if (strstr(str, *it))
|
||||
{
|
||||
filter_out = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!filter_out)
|
||||
{
|
||||
list<sstring>::const_iterator it;
|
||||
for (it = excludes.begin() ; it != excludes.end() ; it++)
|
||||
if (strstr(str, *it))
|
||||
{
|
||||
filter_out = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (filter_out)
|
||||
{
|
||||
|
@ -55,6 +55,7 @@ private:
|
||||
static BOOL CALLBACK FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void InitDialog(HWND hwnd);
|
||||
void HandleMenu();
|
||||
void DeleteSelItems();
|
||||
void AppendLog(char* msg);
|
||||
void WriteToFile();
|
||||
static DWORD WINAPI thread(void* param);
|
||||
|
@ -195,9 +195,9 @@ bool ApiLibraryManager::load_apilib(const char* apilib_name)
|
||||
apilib->index = apilib_cnt;
|
||||
|
||||
//set mod_index for newly loaded api libraries
|
||||
pmteModTable = *ppmteModTable;
|
||||
mr = MRFromHLib(apilib->mod_handle);
|
||||
DBGASSERT(mr);
|
||||
pmteModTable = *ppmteModTable;
|
||||
((IMTE_KEX*) pmteModTable[mr->mteIndex])->mod_index = 0xff00 + apilib->index;
|
||||
|
||||
//add to table of new ApiLibraries
|
||||
|
@ -27,7 +27,9 @@
|
||||
#include "internals.h"
|
||||
#include "DebugWindow.h"
|
||||
|
||||
void* get_process_env_data(const char* env, void* (*c)())
|
||||
#define APILOG_TLS_INDEX 78
|
||||
|
||||
void* get_process_env_data(const char* env, void* (*creator)())
|
||||
{
|
||||
//environment variable: ENV=ProcessID:DATA
|
||||
char buf[20];
|
||||
@ -41,7 +43,7 @@ void* get_process_env_data(const char* env, void* (*c)())
|
||||
|| ProcID != GetCurrentProcessId())
|
||||
{
|
||||
//invalid/missing value - create new data
|
||||
data = c();
|
||||
data = creator();
|
||||
if (data)
|
||||
{
|
||||
sprintf(buf, "%x:%x", GetCurrentProcessId(), data);
|
||||
@ -64,7 +66,11 @@ HANDLE get_process_debug_heap()
|
||||
|
||||
void* tls_creator()
|
||||
{
|
||||
return (void*) TlsAlloc();
|
||||
for (int i = 0 ; i < APILOG_TLS_INDEX+1 ; i++)
|
||||
TlsAlloc();
|
||||
for (int i = 0 ; i < APILOG_TLS_INDEX ; i++)
|
||||
TlsFree(i);
|
||||
return (void*) APILOG_TLS_INDEX;
|
||||
}
|
||||
|
||||
DWORD get_process_debug_tls()
|
||||
@ -75,7 +81,7 @@ DWORD get_process_debug_tls()
|
||||
extern "C"
|
||||
int snprintf(char *buffer, size_t n, const char* format, ...);
|
||||
|
||||
DWORD __stdcall log_api(const char* source, const char* target, const char* api_name, DWORD ret)
|
||||
DWORD __stdcall log_api(const char* source, const char* target, const char* api_name, DWORD depth, DWORD ret)
|
||||
{
|
||||
DebugWindow* dw = DebugWindow::get();
|
||||
if (!dw)
|
||||
@ -83,8 +89,20 @@ DWORD __stdcall log_api(const char* source, const char* target, const char* api_
|
||||
|
||||
char msg[DEBUGMSG_MAXLEN];
|
||||
|
||||
const char* proc = ((*ppmteModTable)[(*pppdbCur)->pExeMODREF->mteIndex])->pszModName;
|
||||
snprintf(msg, sizeof(msg), "%s|%x|%s|%s|%s|%x", proc,
|
||||
//fancy call stack depth indicator
|
||||
if (depth < DEBUGMSG_MAXLEN / 2)
|
||||
{
|
||||
for (int i = 0 ; i < depth ; i++)
|
||||
msg[i] = 'l';
|
||||
}
|
||||
else
|
||||
{
|
||||
msg[0] = 'E';
|
||||
msg[1] = 'E';
|
||||
depth = 2;
|
||||
}
|
||||
|
||||
snprintf(msg + depth, sizeof(msg) - depth, "|%x|%s|%s|%s|%x",
|
||||
GetCurrentThreadId(), source, target, api_name, ret);
|
||||
|
||||
dw->append(msg);
|
||||
@ -97,31 +115,56 @@ ThreadAddrStack::ThreadAddrStack()
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
void __stdcall ThreadAddrStack::push_ret_addr(DWORD tls, DWORD addr)
|
||||
void __stdcall ThreadAddrStack::push_ret_addr(DWORD addr)
|
||||
{
|
||||
ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(tls);
|
||||
//TlsGetValue clears last error value so remember & restore it
|
||||
DWORD lasterr = GetLastError();
|
||||
ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(APILOG_TLS_INDEX);
|
||||
SetLastError(lasterr);
|
||||
if (!tas)
|
||||
{
|
||||
void* mem = HeapAlloc(get_process_debug_heap(), 0, sizeof(ThreadAddrStack));
|
||||
tas = new (mem) ThreadAddrStack;
|
||||
TlsSetValue(tls, mem);
|
||||
TlsSetValue(APILOG_TLS_INDEX, mem);
|
||||
}
|
||||
tas->stack[tas->pos++] = addr;
|
||||
DBGASSERT(tas->pos < sizeof(tas->stack) / sizeof(tas->stack[0]));
|
||||
}
|
||||
|
||||
DWORD __stdcall ThreadAddrStack::pop_ret_addr(DWORD tls)
|
||||
DWORD __stdcall ThreadAddrStack::pop_ret_addr()
|
||||
{
|
||||
ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(tls);
|
||||
if (!tas || !tas->pos)
|
||||
return 0;
|
||||
//TlsGetValue clears last error value so remember & restore it
|
||||
DWORD lasterr = GetLastError();
|
||||
ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(APILOG_TLS_INDEX);
|
||||
SetLastError(lasterr);
|
||||
DBGASSERT(tas->pos > 0);
|
||||
return tas->stack[--tas->pos];
|
||||
}
|
||||
|
||||
DWORD __stdcall ThreadAddrStack::get_level()
|
||||
{
|
||||
//TlsGetValue clears last error value so remember & restore it
|
||||
DWORD lasterr = GetLastError();
|
||||
ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(APILOG_TLS_INDEX);
|
||||
SetLastError(lasterr);
|
||||
return tas->pos;
|
||||
}
|
||||
|
||||
PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig)
|
||||
{
|
||||
HANDLE heap = get_process_debug_heap();
|
||||
char* new_api = (char*) HeapAlloc(heap, 0, strlen(api) + 1);
|
||||
strcpy(new_api, api);
|
||||
get_process_debug_tls();
|
||||
void* mem = HeapAlloc(heap, 0, sizeof(log_stub));
|
||||
return (PROC) new (mem) log_stub(caller,
|
||||
target, api, (unsigned long) orig,
|
||||
(unsigned long) log_api, get_process_debug_tls());
|
||||
target, new_api, (unsigned long) orig,
|
||||
(unsigned long) log_api);
|
||||
}
|
||||
|
||||
PROC create_log_stub(const char* caller, const char* target, WORD ord, PROC orig)
|
||||
{
|
||||
char ord_name[16];
|
||||
snprintf(ord_name, sizeof(ord_name), "Ordinal:%d", ord);
|
||||
return create_log_stub(caller, target, ord_name, orig);
|
||||
}
|
||||
|
@ -29,12 +29,13 @@ class ThreadAddrStack
|
||||
{
|
||||
public:
|
||||
ThreadAddrStack();
|
||||
static void __stdcall push_ret_addr(DWORD tls, DWORD addr);
|
||||
static DWORD __stdcall pop_ret_addr(DWORD tls);
|
||||
static void __stdcall push_ret_addr(DWORD addr);
|
||||
static DWORD __stdcall pop_ret_addr();
|
||||
static DWORD __stdcall get_level();
|
||||
|
||||
private:
|
||||
int pos;
|
||||
DWORD stack[31];
|
||||
DWORD stack[1023];
|
||||
};
|
||||
|
||||
#pragma pack(push,1)
|
||||
@ -44,41 +45,46 @@ class log_stub
|
||||
{
|
||||
public:
|
||||
log_stub(const char* source, const char* target, const char* name,
|
||||
unsigned long proc, unsigned long log_fun, DWORD tls)
|
||||
unsigned long proc, unsigned long log_fun)
|
||||
: call_orig(proc, true), jmp_logfun(log_fun),
|
||||
tas_store((unsigned long) ThreadAddrStack::push_ret_addr, true),
|
||||
tas_restore((unsigned long) ThreadAddrStack::pop_ret_addr, true)
|
||||
tas_restore((unsigned long) ThreadAddrStack::pop_ret_addr, true),
|
||||
tas_depth((unsigned long) ThreadAddrStack::get_level, true)
|
||||
{
|
||||
c_push1 = c_push2 = c_push3 = c_push4 = c_push5 = 0x68;
|
||||
tls1 = tls2 = tls;
|
||||
c_push2 = c_push3 = c_push4 = 0x68;
|
||||
v_source = source;
|
||||
v_target = target;
|
||||
v_name = name;
|
||||
c_pusheax1 = c_pusheax2 = 0x50;
|
||||
c_pusheax1 = c_pusheax2 = c_pusheax3 = c_pusheax4 = 0x50;
|
||||
c_popeax4 = 0x58;
|
||||
c_pushecx = 0x51;
|
||||
c_popecx = 0x59;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char c_push1;
|
||||
DWORD tls1;
|
||||
redir_stub tas_store; //arg1=tls, arg2=caller ret
|
||||
unsigned char c_popeax4; //caller ret
|
||||
unsigned char c_pushecx;
|
||||
unsigned char c_pusheax4; //caller ret
|
||||
redir_stub tas_store;
|
||||
unsigned char c_popecx;
|
||||
redir_stub call_orig;
|
||||
unsigned char c_pusheax1; //orig ret
|
||||
unsigned char c_push2;
|
||||
redir_stub tas_depth;
|
||||
unsigned char c_pusheax3; //call stack depth
|
||||
unsigned char c_push2; //api name
|
||||
const char* v_name;
|
||||
unsigned char c_push3;
|
||||
unsigned char c_push3; //target module
|
||||
const char* v_target;
|
||||
unsigned char c_push4;
|
||||
unsigned char c_push4; //calling module
|
||||
const char* v_source;
|
||||
unsigned char c_push5;
|
||||
DWORD tls2;
|
||||
redir_stub tas_restore; //restore caller ret
|
||||
unsigned char c_pusheax2;
|
||||
redir_stub jmp_logfun; //jmp to log_fun
|
||||
redir_stub tas_restore;
|
||||
unsigned char c_pusheax2; //caller return address
|
||||
redir_stub jmp_logfun; //jump to log_fun
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig);
|
||||
|
||||
PROC create_log_stub(const char* caller, const char* target, WORD ord, PROC orig);
|
||||
|
||||
#endif
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
void dbgvprintf(const char* format, void* _argp);
|
||||
void dbgprintf(const char* format, ...);
|
||||
PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig);
|
||||
|
||||
#include "apilog.h"
|
||||
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@
|
||||
static bool is_winme;
|
||||
HINSTANCE hInstance;
|
||||
|
||||
IMTE*** ppmteModTable = NULL;
|
||||
IMTE*** volatile ppmteModTable = NULL;
|
||||
HMODULE h_kernel32;
|
||||
CRITICAL_SECTION* krnl32lock = NULL;
|
||||
PDB98** pppdbCur = NULL;
|
||||
@ -37,11 +37,11 @@ WORD* pimteMax = NULL;
|
||||
|
||||
MRFromHLib_t MRFromHLib = NULL;
|
||||
TIDtoTDB_t TIDtoTDB = NULL;
|
||||
PIDtoPDB_t PIDtoPDB = NULL;
|
||||
MRLoadTree_t MRLoadTree = NULL;
|
||||
FreeLibTree_t FreeLibTree = NULL;
|
||||
FLoadTreeNotify_t FLoadTreeNotify = NULL;
|
||||
FreeLibRemove_t FreeLibRemove = NULL;
|
||||
AllocHandle_t AllocHandle = NULL;
|
||||
|
||||
sstring kernelex_dir("");
|
||||
sstring own_path("");
|
||||
@ -162,6 +162,25 @@ MODREF* MRfromCallerAddr(DWORD addr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE _OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId)
|
||||
{
|
||||
HANDLE ret;
|
||||
TDB98* tdb = TIDtoTDB(dwThreadId);
|
||||
if (!tdb || tdb->Type != WIN98_K32OBJ_THREAD)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dwDesiredAccess &= THREAD_ALL_ACCESS;
|
||||
if (bInheritHandle)
|
||||
dwDesiredAccess |= 0x80000000;
|
||||
ret = AllocHandle(*pppdbCur, tdb, dwDesiredAccess);
|
||||
if (ret == INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* find win32 mutex */
|
||||
static CRITICAL_SECTION* find_krnl32lock()
|
||||
{
|
||||
@ -273,23 +292,6 @@ static TIDtoTDB_t find_TIDtoTDB()
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PIDtoPDB_t find_PIDtoPDB()
|
||||
{
|
||||
PIDtoPDB_t ret;
|
||||
|
||||
const char* pat_name = "PIDtoPDB";
|
||||
short pat[] = {0xFF,0x74,0x24,0x0C,0xE8,-2,-2,-2,-2};
|
||||
int pat_len = sizeof(pat) / sizeof(short);
|
||||
|
||||
DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, "OpenProcess"), pat_len, pat, pat_len, pat_name);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
ret = (PIDtoPDB_t)decode_calljmp(res);
|
||||
DBGPRINTF(("%s @ 0x%08x\n", pat_name, ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MRLoadTree_t find_MRLoadTree()
|
||||
{
|
||||
MRLoadTree_t ret;
|
||||
@ -370,6 +372,23 @@ static FreeLibRemove_t find_FreeLibRemove()
|
||||
return ret;
|
||||
}
|
||||
|
||||
static AllocHandle_t find_AllocHandle()
|
||||
{
|
||||
AllocHandle_t ret;
|
||||
|
||||
const char* pat_name = "AllocHandle";
|
||||
short pat[] = {0x83,0xD1,0xFF,0x81,0xE2,0xFF,0x0F,0x1F,0x00,0x81,0xE1,0x00,0x00,0x00,0x80,0x0B,0xCA,0x8B,0x15,-1,-1,-1,-1,0x51,0x50,0xFF,0x32,0xE8,-2,-2,-2,-2};
|
||||
int pat_len = sizeof(pat) / sizeof(short);
|
||||
|
||||
DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, "OpenProcess"), 0x80, pat, pat_len, pat_name);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
ret = (AllocHandle_t)decode_calljmp(res);
|
||||
DBGPRINTF(("%s @ 0x%08x\n", pat_name, ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool find_kernelex_install_dir()
|
||||
{
|
||||
//registry value InstallDir is written by the installer
|
||||
@ -424,17 +443,17 @@ int internals_init()
|
||||
MRFromHLib = find_MRFromHLib();
|
||||
pimteMax = find_pimteMax();
|
||||
TIDtoTDB = find_TIDtoTDB();
|
||||
PIDtoPDB = find_PIDtoPDB();
|
||||
MRLoadTree = find_MRLoadTree();
|
||||
FreeLibTree = find_FreeLibTree();
|
||||
FLoadTreeNotify = find_FLoadTreeNotify();
|
||||
FreeLibRemove = find_FreeLibRemove();
|
||||
AllocHandle = find_AllocHandle();
|
||||
bool instdir_rslt = find_kernelex_install_dir();
|
||||
is_winme = (GetVersion() == 0xc0005a04);
|
||||
|
||||
if (!h_kernel32 || !ppmteModTable || !krnl32lock || !pppdbCur || !MRFromHLib
|
||||
|| !pimteMax || !TIDtoTDB || !PIDtoPDB || !MRLoadTree || !FreeLibTree
|
||||
|| !FLoadTreeNotify || !FreeLibRemove || !instdir_rslt)
|
||||
|| !pimteMax || !TIDtoTDB || !MRLoadTree || !FreeLibTree
|
||||
|| !FLoadTreeNotify || !FreeLibRemove || !AllocHandle || !instdir_rslt)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
extern IMTE*** ppmteModTable;
|
||||
extern IMTE*** volatile ppmteModTable;
|
||||
extern HMODULE h_kernel32;
|
||||
extern CRITICAL_SECTION* krnl32lock;
|
||||
extern PDB98** pppdbCur;
|
||||
@ -53,11 +53,11 @@ bool isWinMe();
|
||||
|
||||
typedef MODREF* (__stdcall *MRFromHLib_t)(HMODULE);
|
||||
typedef TDB98* (__stdcall *TIDtoTDB_t)(DWORD);
|
||||
typedef PDB98* (__stdcall *PIDtoPDB_t)(DWORD);
|
||||
typedef MODREF* (__stdcall * MRLoadTree_t)(LPCSTR);
|
||||
typedef BOOL (__stdcall * FreeLibTree_t)(MODREF*);
|
||||
typedef BOOL (__stdcall * FLoadTreeNotify_t)(MODREF*, BOOL);
|
||||
typedef VOID (__stdcall * FreeLibRemove_t)(VOID);
|
||||
typedef HANDLE (__stdcall *AllocHandle_t)(PDB98*, TDB98*, DWORD);
|
||||
|
||||
extern MRFromHLib_t MRFromHLib;
|
||||
|
||||
@ -67,17 +67,13 @@ extern MRFromHLib_t MRFromHLib;
|
||||
*/
|
||||
extern TIDtoTDB_t TIDtoTDB;
|
||||
|
||||
/** Convert Process ID into pointer to Process Database.
|
||||
* @param pid Process ID.
|
||||
* @return Pointer to Process Database.
|
||||
*/
|
||||
extern PIDtoPDB_t PIDtoPDB;
|
||||
|
||||
extern MRLoadTree_t MRLoadTree;
|
||||
extern FreeLibTree_t FreeLibTree;
|
||||
extern FLoadTreeNotify_t FLoadTreeNotify;
|
||||
extern FreeLibRemove_t FreeLibRemove;
|
||||
extern AllocHandle_t AllocHandle;
|
||||
|
||||
MODREF* MRfromCallerAddr(DWORD addr);
|
||||
HANDLE _OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);
|
||||
|
||||
#endif
|
||||
|
@ -62,14 +62,14 @@ PROC kexGetProcAddress(HMODULE hModule, PCSTR lpProcName)
|
||||
return iGetProcAddress(hModule, lpProcName);
|
||||
}
|
||||
|
||||
void* kexPIDtoPDB(DWORD pid)
|
||||
HANDLE kexOpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId)
|
||||
{
|
||||
return PIDtoPDB(pid);
|
||||
return _OpenThread(dwDesiredAccess, bInheritHandle, dwThreadId);
|
||||
}
|
||||
|
||||
void* kexTIDtoTDB(DWORD tid)
|
||||
BOOL kexAreExtensionsEnabled()
|
||||
{
|
||||
return TIDtoTDB(tid);
|
||||
return are_extensions_enabled();
|
||||
}
|
||||
|
||||
void kexGetModuleSettings(const char* module,
|
||||
|
@ -119,7 +119,7 @@ void load_MPRServices()
|
||||
RegOpenKey(hk_serv, subkey, &hk_this);
|
||||
size = sizeof(dllname);
|
||||
if (RegQueryValueEx(hk_this, "DllName", NULL, NULL, (BYTE*)dllname, &size)
|
||||
== ERROR_SUCCESS && strcmpi(dllname, own_path) != 0)
|
||||
== ERROR_SUCCESS)
|
||||
{
|
||||
LoadLibrary(dllname);
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ char system_path[MAX_PATH];
|
||||
int system_path_len;
|
||||
|
||||
static PLONG jtab;
|
||||
static LONG old_jtab[4];
|
||||
|
||||
static LONG old_jtab[JTAB_SIZE];
|
||||
static HKEY known_dlls_key;
|
||||
|
||||
|
||||
/** Get API configuration for selected module.
|
||||
@ -101,6 +101,7 @@ static bool get_config(MODREF* moduleMR, config_params& cp)
|
||||
if (ppdbParent && !(ppdbParent->Flags & (fTerminated | fTerminating |
|
||||
fNearlyTerminating | fDosProcess | fWin16Process)))
|
||||
{
|
||||
pmteModTable = *ppmteModTable;
|
||||
IMTE_KEX* parent = (IMTE_KEX*) pmteModTable[ppdbParent->pExeMODREF->mteIndex];
|
||||
conf = parent->config;
|
||||
flags = parent->flags;
|
||||
@ -128,7 +129,7 @@ static bool get_config(MODREF* moduleMR, config_params& cp)
|
||||
DBGASSERT(conf != NULL);
|
||||
cp.apiconf = conf;
|
||||
#ifdef _DEBUG
|
||||
cp.log_apis = (flags & LDR_LOG_APIS) != 0;
|
||||
cp.log_apis = (process->flags & LDR_LOG_APIS) != 0;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@ -234,7 +235,7 @@ static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod)
|
||||
}
|
||||
|
||||
DBGPRINTF(("Implicit load: replacing tree %s => %s [PID=%08x]\n",
|
||||
pmteModTable[caller->ImplicitImports[*refmod - buffer].pMR->mteIndex]
|
||||
(*ppmteModTable)[caller->ImplicitImports[*refmod - buffer].pMR->mteIndex]
|
||||
->pszModName, apilib->apilib_name,
|
||||
GetCurrentProcessId()));
|
||||
|
||||
@ -261,6 +262,7 @@ static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod)
|
||||
}
|
||||
}
|
||||
|
||||
pmteModTable = *ppmteModTable;
|
||||
IMTE_KEX* imte = (IMTE_KEX*) pmteModTable[mr->mteIndex];
|
||||
|
||||
img_base = imte->pNTHdr->OptionalHeader.ImageBase;
|
||||
@ -462,7 +464,9 @@ DWORD encode_address(DWORD addr, const ApiLibrary* apilib)
|
||||
//STD apilib
|
||||
if (index == 0)
|
||||
{
|
||||
if (addr < 0xc0000000)
|
||||
//normal address (shared or nonshared library)
|
||||
//or ordinal number for export forwarding
|
||||
if (addr < 0xc0000000 || addr >= 0xffff0000)
|
||||
return addr;
|
||||
|
||||
//extremely rare scenario: driver hijacked apis so the address is now
|
||||
@ -526,6 +530,15 @@ PROC WINAPI ExportFromOrdinal(IMTE_KEX* target, MODREF* caller, PMODREF** refmod
|
||||
target->pNTHdr, caller, refmod);
|
||||
else
|
||||
ret = OriExportFromOrdinal(target->pNTHdr, ordinal);
|
||||
#ifdef _DEBUG
|
||||
if (ret && cp.log_apis)
|
||||
{
|
||||
IMTE_KEX* icaller = (IMTE_KEX*)((*ppmteModTable)[caller->mteIndex]);
|
||||
if (DWORD(ret) < target->pNTHdr->OptionalHeader.ImageBase
|
||||
+ target->pNTHdr->OptionalHeader.BaseOfData)
|
||||
ret = create_log_stub(icaller->pszModName, target->pszModName, ordinal, ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
ret = OriExportFromOrdinal(target->pNTHdr, ordinal);
|
||||
@ -568,7 +581,9 @@ PROC WINAPI ExportFromName(IMTE_KEX* target, MODREF* caller, PMODREF** refmod, W
|
||||
if (ret && cp.log_apis)
|
||||
{
|
||||
IMTE_KEX* icaller = (IMTE_KEX*)((*ppmteModTable)[caller->mteIndex]);
|
||||
ret = create_log_stub(icaller->pszModName, target->pszModName, name, ret);
|
||||
if (DWORD(ret) < target->pNTHdr->OptionalHeader.ImageBase
|
||||
+ target->pNTHdr->OptionalHeader.BaseOfData)
|
||||
ret = create_log_stub(icaller->pszModName, target->pszModName, name, ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -585,6 +600,50 @@ PROC WINAPI ExportFromName(IMTE_KEX* target, MODREF* caller, PMODREF** refmod, W
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool are_extensions_enabled()
|
||||
{
|
||||
config_params cp;
|
||||
MODREF* exe = (*pppdbCur)->pExeMODREF;
|
||||
return get_config(exe, cp);
|
||||
}
|
||||
|
||||
typedef BOOL (__stdcall *IsKnownDLL_t)(char*, const char*);
|
||||
|
||||
static BOOL WINAPI IsKnownKexDLL(char* name, const char* ext)
|
||||
{
|
||||
LONG res;
|
||||
DWORD type;
|
||||
char path[MAX_PATH];
|
||||
DWORD size = sizeof(path);
|
||||
|
||||
if (ext && strcmp(ext, "DLL") != 0)
|
||||
return FALSE;
|
||||
|
||||
if (are_extensions_enabled())
|
||||
{
|
||||
//workaround windows bug
|
||||
int pos = strlen(name) - 4;
|
||||
if (pos > 0 && name[pos] == '.')
|
||||
name[pos] = '\0';
|
||||
|
||||
res = RegQueryValueEx(known_dlls_key, name, NULL, &type, (BYTE*) path, &size);
|
||||
}
|
||||
else
|
||||
res = ERROR_INVALID_FUNCTION;
|
||||
|
||||
if (res == ERROR_SUCCESS && type == REG_SZ)
|
||||
{
|
||||
memcpy(name, (const char*) kernelex_dir, kernelex_dir.length());
|
||||
memcpy(name + kernelex_dir.length(), path, size);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsKnownDLL_t IsKnownDLL = (IsKnownDLL_t) old_jtab[JTAB_KNO_DLL];
|
||||
return IsKnownDLL(name, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
PROC WINAPI iGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
||||
{
|
||||
IMAGE_DOS_HEADER* dos_hdr;
|
||||
@ -708,6 +767,7 @@ int resolver_init()
|
||||
jtab = (PLONG) dseg->jtab;
|
||||
|
||||
system_path_len = GetSystemDirectory(system_path, sizeof(system_path));
|
||||
RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\KernelEx\\KnownDLLs", &known_dlls_key);
|
||||
|
||||
SettingsDB::instance.flush_all();
|
||||
|
||||
@ -716,6 +776,8 @@ int resolver_init()
|
||||
|
||||
void resolver_uninit()
|
||||
{
|
||||
DBGPRINTF(("resolver_uninit()\n"));
|
||||
RegCloseKey(known_dlls_key);
|
||||
SettingsDB::instance.clear();
|
||||
reset_imtes();
|
||||
}
|
||||
@ -723,17 +785,16 @@ void resolver_uninit()
|
||||
void resolver_hook()
|
||||
{
|
||||
DBGPRINTF(("resolver_hook()\n"));
|
||||
old_jtab[0] = InterlockedExchange(jtab + JTAB_EFO_DYN, (LONG) ExportFromOrdinalDynamic_thunk);
|
||||
old_jtab[1] = InterlockedExchange(jtab + JTAB_EFO_STA, (LONG) ExportFromOrdinalStatic_thunk);
|
||||
old_jtab[2] = InterlockedExchange(jtab + JTAB_EFN_DYN, (LONG) ExportFromNameDynamic_thunk);
|
||||
old_jtab[3] = InterlockedExchange(jtab + JTAB_EFN_STA, (LONG) ExportFromNameStatic_thunk);
|
||||
old_jtab[JTAB_EFO_DYN] = InterlockedExchange(jtab + JTAB_EFO_DYN, (LONG) ExportFromOrdinalDynamic_thunk);
|
||||
old_jtab[JTAB_EFO_STA] = InterlockedExchange(jtab + JTAB_EFO_STA, (LONG) ExportFromOrdinalStatic_thunk);
|
||||
old_jtab[JTAB_EFN_DYN] = InterlockedExchange(jtab + JTAB_EFN_DYN, (LONG) ExportFromNameDynamic_thunk);
|
||||
old_jtab[JTAB_EFN_STA] = InterlockedExchange(jtab + JTAB_EFN_STA, (LONG) ExportFromNameStatic_thunk);
|
||||
old_jtab[JTAB_KNO_DLL] = InterlockedExchange(jtab + JTAB_KNO_DLL, (LONG) IsKnownKexDLL);
|
||||
}
|
||||
|
||||
void resolver_unhook()
|
||||
{
|
||||
DBGPRINTF(("resolver_unhook()\n"));
|
||||
InterlockedExchange(jtab + JTAB_EFO_DYN, old_jtab[0]);
|
||||
InterlockedExchange(jtab + JTAB_EFO_STA, old_jtab[1]);
|
||||
InterlockedExchange(jtab + JTAB_EFN_DYN, old_jtab[2]);
|
||||
InterlockedExchange(jtab + JTAB_EFN_STA, old_jtab[3]);
|
||||
for (int i = 0 ; i < JTAB_SIZE ; i++)
|
||||
InterlockedExchange(jtab + i, old_jtab[i]);
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ struct config_params
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
bool are_extensions_enabled();
|
||||
DWORD encode_address(DWORD addr, const ApiLibrary* apilib);
|
||||
PROC WINAPI iGetProcAddress(HMODULE hModule, LPCSTR lpProcName);
|
||||
PROC WINAPI ExportFromOrdinal(IMTE_KEX* target, MODREF* caller, PMODREF** refmod, WORD ordinal);
|
||||
|
@ -249,7 +249,8 @@ typedef struct _TDBX98 TDBX98;
|
||||
|
||||
// Thread database (FS:[0x18] - 0x8)
|
||||
typedef struct _TDB98 { // Size = 0x228 (from Kernel32)
|
||||
WORD Type; // 00 K32 object type
|
||||
BYTE Type; // 00 K32 object type
|
||||
BYTE Unknown_A; // 01
|
||||
WORD cReference; // 02 Reference count
|
||||
DWORD pSomeEvent; // 04 K32 event object used when someone waits on the thread object
|
||||
TIB98 tib; // 08 Thread information block (TIB)
|
||||
@ -266,7 +267,8 @@ typedef struct _TDB98 { // Size = 0x228 (from Kernel32)
|
||||
} TDB98, *PTDB98;
|
||||
|
||||
typedef struct _TDBME { // Size = 0x228 (from Kernel32)
|
||||
WORD Type; // 00 K32 object type
|
||||
BYTE Type; // 00 K32 object type
|
||||
BYTE Unknown_A; // 01
|
||||
WORD cReference; // 02 Reference count
|
||||
DWORD pSomeEvent; // 04 K32 event object used when someone waits on the thread object
|
||||
TIB98 tib; // 08 Thread information block (TIB)
|
||||
|
Reference in New Issue
Block a user