1
0
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:
UzixLS
2018-11-03 16:20:27 +03:00
parent 30df122aba
commit d6aad6c6c5
43 changed files with 624 additions and 256 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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,

View File

@ -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);
}

View File

@ -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]);
}

View File

@ -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);

View File

@ -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)