Skip to content

Commit

Permalink
added support for js
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed Jun 16, 2022
1 parent c6033f0 commit 9b6fb18
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 12 deletions.
12 changes: 11 additions & 1 deletion ClrDumper/Source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void main(int argc, char* argv[])
lstrcatA(dll,"\\HookClr.dll");
if (argc < 3)
{
printf("ClrDumper.exe [-nativeclr|-asmload|-vbscript] [FULL_PATH_TO_EXE|FULL_PATH_TO_VBS]");
printf("ClrDumper.exe [-nativeclr|-asmload|-vbscript|-jscript] [FULL_PATH_TO_EXE|FULL_PATH_TO_VBS|FULL_PATH_TO_JS]");
return;
}
lstrcpyA(pefile, argv[2]);
Expand All @@ -135,6 +135,16 @@ void main(int argc, char* argv[])

_intKeyMap[HOOK_TYPE] = VBSCRIPT_ARG;
}
else if (lstrcmpA(argv[1], "-jscript") == 0)
{
char buff[MAX_PATH];
GetSystemDirectoryA(buff, MAX_PATH);
lstrcatA(buff, "\\wscript.exe");
lstrcpyA(pefile, buff);
sprintf(script_path, "%s %s", pefile, argv[2]);

_intKeyMap[HOOK_TYPE] = JSCRIPT_ARG;
}
else
{
printf("[-] Invalid arguments");
Expand Down
2 changes: 2 additions & 0 deletions HookClr/HookClr.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
<ItemGroup>
<ClCompile Include="AssemblyLoadHook.cpp" />
<ClCompile Include="DllLoadCallback.cpp" />
<ClCompile Include="JScriptHook.cpp" />
<ClCompile Include="kmp.cpp" />
<ClCompile Include="MemoryUtils.cpp" />
<ClCompile Include="NamedPipeIO.cpp" />
Expand All @@ -156,6 +157,7 @@
<ItemGroup>
<ClInclude Include="AssemblyLoadHook.h" />
<ClInclude Include="DllLoadCallback.h" />
<ClInclude Include="JScriptHook.h" />
<ClInclude Include="kmp.h" />
<ClInclude Include="MemoryUtils.h" />
<ClInclude Include="NamedPipeIO.h" />
Expand Down
6 changes: 6 additions & 0 deletions HookClr/HookClr.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
<ClCompile Include="kmp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JScriptHook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AssemblyLoadHook.h">
Expand All @@ -68,5 +71,8 @@
<ClInclude Include="kmp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JScriptHook.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
98 changes: 98 additions & 0 deletions HookClr/JScriptHook.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include "JScriptHook.h"
#include "DllLoadCallback.h"
#include "NamedPipeIO.h"
#include "MemoryUtils.h"
#include "MinHook.h"
#include "utility.h"

namespace JScript {

char _dumpPath[MAX_PATH];

unsigned char pattern_COleScript_Compile[8] = { 0xFF,0x75,0xFC,0xFF,0x75,0x08,0x50,0xE8 };
unsigned char pattern_Parser_ParseSourceCall[2] = { 0x50,0xe8 };
unsigned int _compileAddress = 0;
unsigned int _parserAddress = 0;


void UnhookForJScript()
{
Log("[+] JScript Hook Disabled!");
MH_DisableHook((LPVOID)_parserAddress);
}


typedef int(__thiscall* Parser_ParseSource_t)(void* thiz, void*, void*, const unsigned __int16*, unsigned int, void*, UINT len, void*, const unsigned __int16*, void*);
Parser_ParseSource_t originalParseSource = 0;

int __fastcall parserHooked(void* thiz, void* _notused, void* a, void* b, const unsigned __int16* c, unsigned int d, void* e, UINT len, void* f, const unsigned __int16* g, void* h)
{
char path[MAX_PATH];
lstrcpyA(path, _dumpPath);

char* dumpName = GetDumpName("JS_SCRIPT");
lstrcatA(path, dumpName);

HANDLE hFile = CreateFileA(path,
GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
DWORD dwBytesRead;
int size = wcslen((const wchar_t*)c);
char* buffer = (char*)malloc(size + 1);
wsprintfA(buffer, "%ls", c);
WriteFile(hFile, buffer, size, &dwBytesRead, NULL);
CloseHandle(hFile);
Log("[+] Dump written to %s", path);
}
else
Log("[-] Could not create dump file!");


return originalParseSource(thiz, a, b, c, d, e, len, f,g,h);
}

//in case of jscript the complete code is compiled in one go, later on in case of eval Parser::ParseSource
// function is called, so we will hook that to dump the eval code also
void HookJScript(void* base)
{

unsigned int index = FindDataInDLL(base, pattern_COleScript_Compile, 8);
_compileAddress = *(unsigned int*)((unsigned char*)index + 8) + (index + 7 + 5); //its a relative address
//in the function COleScript_Compile, there is a call to Parser::ParseSource, we will find that
index = FindData((unsigned char*)_compileAddress, 0x180, pattern_Parser_ParseSourceCall, 2, false);
_parserAddress = *(unsigned int*)((unsigned char*)index + 2) + (index + 1 + 5);

MH_STATUS st;
if ((st = MH_CreateHook((LPVOID)_parserAddress, &parserHooked,
reinterpret_cast<LPVOID*>(&originalParseSource))) != MH_OK)
{
Log("[-] Cannot Create Hook! %s", MH_StatusToString(st));
return;
}
if (MH_EnableHook((LPVOID)_parserAddress) != MH_OK)
{
Log("[-] Cannot Enable Hook!");
return;
}
Log("[+] Target Hooked");
}

void callback(PVOID base, char* name, char* path)
{
if (!lstrcmpA(name, "jscript.dll"))
{
Log("[+] Jscript.dll Loaded! at 0x%x", base);
//symbols are not resolved till now in loaded dll
HookJScript(base);
}
}

void HookForJScript(char* dumpPath)
{
lstrcpyA(_dumpPath, dumpPath);
//we have to wait for jscript.dll to load
module_loaded_callback_t dllcallback = callback;
RegisterLoadDllCalback(dllcallback);
}
}
4 changes: 4 additions & 0 deletions HookClr/JScriptHook.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace JScript {
void UnhookForJScript();
void HookForJScript(char* dumpPath);
}
11 changes: 8 additions & 3 deletions HookClr/MemoryUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
#include "NamedPipeIO.h"
#include "kmp.h"

unsigned int FindData(unsigned char* address, int address_len, unsigned char* needle, int needle_len)
//generic search
unsigned int FindData(unsigned char* address, int address_len, unsigned char* needle, int needle_len, bool wildcard=false)
{
int index = KMPSearch((unsigned char*)needle, needle_len, (unsigned char*)address, address_len);
int index = -1;
if (wildcard)
index = KMPSearchWild((unsigned char*)needle, needle_len, (unsigned char*)address, address_len);
else
index = KMPSearch((unsigned char*)needle, needle_len, (unsigned char*)address, address_len);
if (index == -1)
return index;
return (unsigned int)address + index;
Expand All @@ -17,6 +22,7 @@ unsigned int FindStringInDLL(void* dllBase,const char* needle)
return FindDataInDLL(dllBase, (unsigned char*)needle, lstrlenA(needle));
}

//searchs in dll sections
unsigned int FindDataInDLL(void* dllBase, unsigned char* needle, int needle_size)
{
int index = -1;
Expand All @@ -31,7 +37,6 @@ unsigned int FindDataInDLL(void* dllBase, unsigned char* needle, int needle_size
char section_name[9];
memcpy(section_name, sectionHeader[i].Name, 8);
section_name[8] = 0;
Log("section_name : %s", section_name);
unsigned int section_address = (unsigned int)dllBase + sectionHeader[i].VirtualAddress;
int section_size = sectionHeader[i].Misc.VirtualSize;

Expand Down
2 changes: 1 addition & 1 deletion HookClr/MemoryUtils.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
unsigned int FindStringInDLL(void* dllBase,const char* needle);
unsigned int FindDataInDLL(void* dllBase, unsigned char* needle, int needle_size);
unsigned int FindData(unsigned char* address, int address_len, unsigned char* needle, int needle_len);
unsigned int FindData(unsigned char* address, int address_len, unsigned char* needle, int needle_len, bool wildcard);
8 changes: 8 additions & 0 deletions HookClr/Source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "NativeClrHook.h"
#include "NamedPipeIO.h"
#include "VBScript.h"
#include "JScriptHook.h"


#pragma comment(lib,"Shlwapi.lib")
Expand Down Expand Up @@ -66,6 +67,9 @@ void UnhookFunctions()
case VBSCRIPT_ARG:
VBScript::UnhookForVBScript();
break;
case JSCRIPT_ARG:
JScript::UnhookForJScript();
break;
default:
break;
}
Expand Down Expand Up @@ -99,6 +103,10 @@ void HookFunctions()
Log("[+] Hooking for VBScript!");
VBScript::HookForVBScript(dumpPath);
break;
case JSCRIPT_ARG:
Log("[+] Hooking for JScript!");
JScript::HookForJScript(dumpPath);
break;
default:
break;
}
Expand Down
12 changes: 6 additions & 6 deletions HookClr/VBScriptHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
namespace VBScript {

char _dumpPath[MAX_PATH];
//confirmed from vbscript.dll version 5.812.10586.494(modified 2016) till 5.812.10240.16384 (modified 2022)
unsigned char pattern_COleScript_Compile[8] = { 0xFF,0x75,0xFC,0xFF,0x75,0x08,0x50,0xE8 };
unsigned int _compileAddress = 0;


void UnhookForVBScript()
Expand Down Expand Up @@ -48,23 +51,20 @@ namespace VBScript {
return originalCompile(thiz, a,b,c,d,e,f,g,h,i);
}

//confirmed from vbscript.dll version 5.812.10586.494(modified 2016) till 5.812.10240.16384 (modified 2022)
unsigned char pattern_COleScript_Compile[8] = { 0xFF,0x75,0xFC,0xFF,0x75,0x08,0x50,0xE8 };

void HookVbScript(void* vbBase)
{

unsigned int index = FindDataInDLL(vbBase, pattern_COleScript_Compile, 8);
unsigned int address = *(unsigned int*)((unsigned char*)index + 8) + (index+7+5); //its a relative address
unsigned int _compileAddress = *(unsigned int*)((unsigned char*)index + 8) + (index+7+5); //its a relative address

MH_STATUS st;
if ((st = MH_CreateHook((LPVOID)address, &compileHooked,
if ((st = MH_CreateHook((LPVOID)_compileAddress, &compileHooked,
reinterpret_cast<LPVOID*>(&originalCompile))) != MH_OK)
{
Log("[-] Cannot Create Hook! %s", MH_StatusToString(st));
return;
}
if (MH_EnableHook((LPVOID)address) != MH_OK)
if (MH_EnableHook((LPVOID)_compileAddress) != MH_OK)
{
Log("[-] Cannot Enable Hook!");
return;
Expand Down
60 changes: 60 additions & 0 deletions HookClr/kmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ int KMPSearch(unsigned char* pat, int patlen, unsigned char* txt, int txtLen)
}
if (j == M) {
//matchFound++;
//free(lps);
return i - j;
j = lps[j - 1];
}
Expand All @@ -52,5 +53,64 @@ int KMPSearch(unsigned char* pat, int patlen, unsigned char* txt, int txtLen)
i = i + 1;
}
}
//free(lps);
return -1;
}

//wildcard kmp implememntation
char WILDCARD = '?';
void computeLPSArrayWild(unsigned char* pat, int M, int* lps)
{
int len = 0;
lps[0] = 0;
int i = 1;
while (i < M) {
if (pat[i] == pat[len] || pat[i] == WILDCARD || pat[len] == WILDCARD) {
len++;
lps[i] = len;
i++;
}
else
{
if (len != 0) {
len = lps[len - 1];
}
else
{
lps[i] = 0;
i++;
}
}
}
}

int KMPSearchWild(unsigned char* pat, int patlen, unsigned char* txt, int txtLen)
{
//matchFound = 0;
int M = patlen;
int N = txtLen;
int* lps = (int*)malloc(M);
computeLPSArrayWild(pat, M, lps);
int i = 0;
int j = 0;
while (i < N) {
if (pat[j] == txt[i] || pat[j] == WILDCARD) {
j++;
i++;
}
if (j == M) {
//matchFound++;
free(lps);
return i - j;
j = lps[j - 1];
}
else if (i < N && pat[j] != txt[i]) {
if (j != 0)
j = lps[j - 1];
else
i = i + 1;
}
}
free(lps);
return -1;
}
3 changes: 2 additions & 1 deletion HookClr/kmp.h
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
int KMPSearch(unsigned char* pat, int patlen, unsigned char* txt, int txtLen);
int KMPSearch(unsigned char* pat, int patlen, unsigned char* txt, int txtLen);
int KMPSearchWild(unsigned char* pat, int patlen, unsigned char* txt, int txtLen);
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ For VbScript
ClrDumper.exe -vbscript [PATH_TO_VBS]
```

For JScript
```
ClrDumper.exe -jscript [PATH_TO_JS]
```

ClrDumper injects HookClr.dll into the processes, please ensure the dll is in the same directory
as ClrDumper.exe

Expand Down

0 comments on commit 9b6fb18

Please sign in to comment.