diff --git a/README.md b/README.md
index 1098433..030a1dc 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ managed by [vx-underground](https://vx-underground.org) | follow us on [Twitter]
# VX-API
-Version: 2.0.477
+Version: 2.0.488
Developer: smelly__vx
@@ -40,7 +40,8 @@ You're free to use this in any manner you please. You do not need to use this en
| StringRemoveSubstring | smelly__vx | String Manipulation |
| StringTerminateStringAtChar | smelly__vx | String Manipulation |
| StringToken | Apple (c) 1999 | String Manipulation |
-| ZeroMemoryEx | ReactOS | String Manipulation |
+| ZeroMemoryEx | ReactOS | String Manipulation |
+| ConvertCharacterStringToIntegerUsingNtdll | smelly__vx | String Manipulation |
| AdfCloseHandleOnInvalidAddress | Checkpoint Research | Anti-debug |
| AdfIsCreateProcessDebugEventCodeSet | Checkpoint Research | Anti-debug |
| AdfOpenProcessOnCsrss | Checkpoint Research | Anti-debug |
@@ -61,6 +62,7 @@ You're free to use this in any manner you please. You do not need to use this en
| CreatePseudoRandomInteger | Apple (c) 1999 | Cryptography Related |
| CreatePseudoRandomString | smelly__vx | Cryptography Related |
| HashFileByMsiFileHashTable | smelly__vx | Cryptography Related |
+| CreatePseudoRandomIntegerFromNtdll | smelly__vx | Cryptography Related |
| GetLastErrorFromTeb | smelly__vx | Error Handling |
| GetLastNtStatusFromTeb | smelly__vx | Error Handling |
| RtlNtStatusToDosErrorViaImport | ReactOS | Error Handling |
@@ -82,6 +84,8 @@ You're free to use this in any manner you please. You do not need to use this en
| HookEngineUnhookHeapFree | rad9800 | Evasion |
| SleepObfuscationViaVirtualProtect | 5pider | Evasion |
| RemoveRegisterDllNotification | Rad98, Peter Winter-Smith | Evasion |
+| CreateProcessByWindowsRHotKey | smelly__vx | Evasion |
+| CreateProcessByWindowsRHotKeyEx | smelly__vx | Evasion |
| GetCurrentLocaleFromTeb | 3xp0rt | Fingerprinting |
| GetNumberOfLinkedDlls | smelly__vx | Fingerprinting |
| GetOsBuildNumberFromPeb | smelly__vx | Fingerprinting |
diff --git a/VX-API/ConvertCharacterStringToIntegerUsingNtdll.cpp b/VX-API/ConvertCharacterStringToIntegerUsingNtdll.cpp
new file mode 100644
index 0000000..02f8f5e
--- /dev/null
+++ b/VX-API/ConvertCharacterStringToIntegerUsingNtdll.cpp
@@ -0,0 +1,44 @@
+#include "Win32Helper.h"
+
+ULONG ConvertCharacterStringToIntegerUsingNtdllA(_In_ PCHAR InString)
+{
+ RTLCHARTOINTEGER RtlCharToInteger = NULL;
+ HMODULE hModule = NULL;
+ ULONG ConvertedString = ERROR_SUCCESS;
+
+ hModule = GetModuleHandleEx2W(L"ntdll.dll");
+ if (hModule == NULL)
+ return 0;
+
+ RtlCharToInteger = (RTLCHARTOINTEGER)GetProcAddressA((DWORD64)hModule, "RtlCharToInteger");
+ if (!RtlCharToInteger)
+ return 0;
+
+ if (RtlCharToInteger(InString, 10, &ConvertedString) != STATUS_SUCCESS)
+ return 0;
+
+ return ConvertedString;
+}
+
+ULONG ConvertCharacterStringToIntegerUsingNtdllW(_In_ PWCHAR InString)
+{
+ RTLCHARTOINTEGER RtlCharToInteger = NULL;
+ HMODULE hModule = NULL;
+ ULONG ConvertedString = ERROR_SUCCESS;
+ CHAR pBuffer[MAX_PATH] = { 0 };
+
+ hModule = GetModuleHandleEx2W(L"ntdll.dll");
+ if (hModule == NULL)
+ return 0;
+
+ RtlCharToInteger = (RTLCHARTOINTEGER)GetProcAddressA((DWORD64)hModule, "RtlCharToInteger");
+ if (!RtlCharToInteger)
+ return 0;
+
+ WCharStringToCharString(pBuffer, InString, StringLengthW((PWCHAR)InString));
+
+ if (RtlCharToInteger(pBuffer, 10, &ConvertedString) != STATUS_SUCCESS)
+ return 0;
+
+ return ConvertedString;
+}
\ No newline at end of file
diff --git a/VX-API/CreateProcessByWindowsRHotKey.cpp b/VX-API/CreateProcessByWindowsRHotKey.cpp
new file mode 100644
index 0000000..811a964
--- /dev/null
+++ b/VX-API/CreateProcessByWindowsRHotKey.cpp
@@ -0,0 +1,133 @@
+#include "Win32Helper.h"
+
+DWORD CreateProcessByWindowsRHotKeyW(_In_ PWCHAR FullPathToBinary)
+{
+ INPUT ExecuteHotkey[4] = { 0 };
+ INPUT BinaryInputBuffer[2] = { 0 };
+ INPUT ExecuteBinaryCommand[2] = { 0 };
+ UINT Result = ERROR_SUCCESS;
+ HWND RunWindow = NULL;
+
+ ExecuteHotkey[0].type = INPUT_KEYBOARD;
+ ExecuteHotkey[0].ki.wVk = VK_LWIN;
+
+ ExecuteHotkey[1].type = INPUT_KEYBOARD;
+ ExecuteHotkey[1].ki.wVk = 0x52;
+
+ ExecuteHotkey[2].type = INPUT_KEYBOARD;
+ ExecuteHotkey[2].ki.wVk = 0x52;
+ ExecuteHotkey[2].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ ExecuteHotkey[3].type = INPUT_KEYBOARD;
+ ExecuteHotkey[3].ki.wVk = VK_LWIN;
+ ExecuteHotkey[3].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ Result = SendInput(ARRAYSIZE(ExecuteHotkey), ExecuteHotkey, sizeof(INPUT));
+ if (Result != ARRAYSIZE(ExecuteHotkey))
+ return Win32FromHResult(Result);
+
+ Sleep(100);
+
+ RunWindow = FindWindowW(NULL, L"Run");
+ if (RunWindow == NULL)
+ return GetLastErrorFromTeb();
+
+ if(!AttachThreadInput(GetCurrentThreadId(), GetWindowThreadProcessId(GetAncestor(RunWindow, GA_ROOT), NULL), TRUE))
+ return GetLastErrorFromTeb();
+
+ if(SetFocus(RunWindow) == NULL)
+ return GetLastErrorFromTeb();
+
+ for (DWORD dwX = 0; dwX < StringLengthW(FullPathToBinary); dwX++)
+ {
+ BinaryInputBuffer[0].type = INPUT_KEYBOARD;
+ BinaryInputBuffer[0].ki.wVk = VkKeyScanW(FullPathToBinary[dwX]);
+
+ BinaryInputBuffer[1].type = INPUT_KEYBOARD;
+ BinaryInputBuffer[1].ki.wVk = VkKeyScanW(FullPathToBinary[dwX]);
+ BinaryInputBuffer[1].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ Result = SendInput(ARRAYSIZE(BinaryInputBuffer), BinaryInputBuffer, sizeof(INPUT));
+ if (Result != ARRAYSIZE(BinaryInputBuffer))
+ return Win32FromHResult(Result);
+ }
+
+ ExecuteBinaryCommand[0].type = INPUT_KEYBOARD;
+ ExecuteBinaryCommand[0].ki.wVk = 0x0D;
+
+ ExecuteBinaryCommand[1].type = INPUT_KEYBOARD;
+ ExecuteBinaryCommand[1].ki.wVk = 0x0D;
+ ExecuteBinaryCommand[1].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ Result = SendInput(ARRAYSIZE(ExecuteBinaryCommand), ExecuteBinaryCommand, sizeof(INPUT));
+ if (Result != ARRAYSIZE(ExecuteBinaryCommand))
+ return Win32FromHResult(Result);
+
+ return ERROR_SUCCESS;
+}
+
+DWORD CreateProcessByWindowsRHotKeyA(_In_ PCHAR FullPathToBinary)
+{
+ INPUT ExecuteHotkey[4] = { 0 };
+ INPUT BinaryInputBuffer[2] = { 0 };
+ INPUT ExecuteBinaryCommand[2] = { 0 };
+ UINT Result = ERROR_SUCCESS;
+ HWND RunWindow = NULL;
+
+ ExecuteHotkey[0].type = INPUT_KEYBOARD;
+ ExecuteHotkey[0].ki.wVk = VK_LWIN;
+
+ ExecuteHotkey[1].type = INPUT_KEYBOARD;
+ ExecuteHotkey[1].ki.wVk = 0x52;
+
+ ExecuteHotkey[2].type = INPUT_KEYBOARD;
+ ExecuteHotkey[2].ki.wVk = 0x52;
+ ExecuteHotkey[2].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ ExecuteHotkey[3].type = INPUT_KEYBOARD;
+ ExecuteHotkey[3].ki.wVk = VK_LWIN;
+ ExecuteHotkey[3].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ Result = SendInput(ARRAYSIZE(ExecuteHotkey), ExecuteHotkey, sizeof(INPUT));
+ if (Result != ARRAYSIZE(ExecuteHotkey))
+ return Win32FromHResult(Result);
+
+ Sleep(100);
+
+ RunWindow = FindWindowW(NULL, L"Run");
+ if (RunWindow == NULL)
+ return GetLastErrorFromTeb();
+
+ if (!AttachThreadInput(GetCurrentThreadId(), GetWindowThreadProcessId(GetAncestor(RunWindow, GA_ROOT), NULL), TRUE))
+ return GetLastErrorFromTeb();
+
+ if (SetFocus(RunWindow) == NULL)
+ return GetLastErrorFromTeb();
+
+ for (DWORD dwX = 0; dwX < StringLengthA(FullPathToBinary); dwX++)
+ {
+ BinaryInputBuffer[0].type = INPUT_KEYBOARD;
+ BinaryInputBuffer[0].ki.wVk = VkKeyScanA(FullPathToBinary[dwX]);
+
+ BinaryInputBuffer[1].type = INPUT_KEYBOARD;
+ BinaryInputBuffer[1].ki.wVk = VkKeyScanA(FullPathToBinary[dwX]);
+ BinaryInputBuffer[1].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ Result = SendInput(ARRAYSIZE(BinaryInputBuffer), BinaryInputBuffer, sizeof(INPUT));
+ if (Result != ARRAYSIZE(BinaryInputBuffer))
+ return Win32FromHResult(Result);
+ }
+
+ ExecuteBinaryCommand[0].type = INPUT_KEYBOARD;
+ ExecuteBinaryCommand[0].ki.wVk = 0x0D;
+
+ ExecuteBinaryCommand[1].type = INPUT_KEYBOARD;
+ ExecuteBinaryCommand[1].ki.wVk = 0x0D;
+ ExecuteBinaryCommand[1].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ Result = SendInput(ARRAYSIZE(ExecuteBinaryCommand), ExecuteBinaryCommand, sizeof(INPUT));
+ if (Result != ARRAYSIZE(ExecuteBinaryCommand))
+ return Win32FromHResult(Result);
+
+ return ERROR_SUCCESS;
+}
\ No newline at end of file
diff --git a/VX-API/CreateProcessByWindowsRHotKeyEx.cpp b/VX-API/CreateProcessByWindowsRHotKeyEx.cpp
new file mode 100644
index 0000000..ed0f7a4
--- /dev/null
+++ b/VX-API/CreateProcessByWindowsRHotKeyEx.cpp
@@ -0,0 +1,113 @@
+#include "Win32Helper.h"
+
+DWORD CreateProcessByWindowsRHotKeyExW(_In_ PWCHAR FullPathToBinary)
+{
+ HWND RunWindow = NULL;
+ HWND EditWindow = NULL;
+ HWND TopWindowForChildElement = NULL;
+ INPUT ExecuteHotkey[4] = { 0 };
+ UINT Result = ERROR_SUCCESS;
+
+ ExecuteHotkey[0].type = INPUT_KEYBOARD;
+ ExecuteHotkey[0].ki.wVk = VK_LWIN;
+
+ ExecuteHotkey[1].type = INPUT_KEYBOARD;
+ ExecuteHotkey[1].ki.wVk = 0x52;
+
+ ExecuteHotkey[2].type = INPUT_KEYBOARD;
+ ExecuteHotkey[2].ki.wVk = 0x52;
+ ExecuteHotkey[2].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ ExecuteHotkey[3].type = INPUT_KEYBOARD;
+ ExecuteHotkey[3].ki.wVk = VK_LWIN;
+ ExecuteHotkey[3].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ Result = SendInput(ARRAYSIZE(ExecuteHotkey), ExecuteHotkey, sizeof(INPUT));
+ if (Result != ARRAYSIZE(ExecuteHotkey))
+ return Win32FromHResult(Result);
+
+ Sleep(100);
+
+ RunWindow = FindWindowW(NULL, L"Run");
+ if (RunWindow == NULL)
+ return GetLastErrorFromTeb();
+
+ if (!AttachThreadInput(GetCurrentThreadId(), GetWindowThreadProcessId(GetAncestor(RunWindow, GA_ROOT), NULL), TRUE))
+ return GetLastErrorFromTeb();
+
+ TopWindowForChildElement = FindWindowExW(RunWindow, NULL, L"ComboBox", NULL);
+ if (TopWindowForChildElement == NULL)
+ return GetLastErrorFromTeb();
+
+ EditWindow = FindWindowExW(TopWindowForChildElement, NULL, L"Edit", NULL);
+ if (EditWindow == NULL)
+ return GetLastErrorFromTeb();
+
+ if (SetFocus(RunWindow) == NULL)
+ return GetLastErrorFromTeb();
+
+ for (DWORD dwX = 0; dwX < StringLengthW(FullPathToBinary); dwX++)
+ {
+ PostMessageW(EditWindow, WM_CHAR, (WCHAR)FullPathToBinary[dwX], 0);
+ }
+
+ PostMessageW(RunWindow, WM_KEYDOWN, VK_RETURN, NULL);
+
+ return ERROR_SUCCESS;
+}
+
+DWORD CreateProcessByWindowsRHotKeyExA(_In_ PCHAR FullPathToBinary)
+{
+ HWND RunWindow = NULL;
+ HWND EditWindow = NULL;
+ HWND TopWindowForChildElement = NULL;
+ INPUT ExecuteHotkey[4] = { 0 };
+ UINT Result = ERROR_SUCCESS;
+
+ ExecuteHotkey[0].type = INPUT_KEYBOARD;
+ ExecuteHotkey[0].ki.wVk = VK_LWIN;
+
+ ExecuteHotkey[1].type = INPUT_KEYBOARD;
+ ExecuteHotkey[1].ki.wVk = 0x52;
+
+ ExecuteHotkey[2].type = INPUT_KEYBOARD;
+ ExecuteHotkey[2].ki.wVk = 0x52;
+ ExecuteHotkey[2].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ ExecuteHotkey[3].type = INPUT_KEYBOARD;
+ ExecuteHotkey[3].ki.wVk = VK_LWIN;
+ ExecuteHotkey[3].ki.dwFlags = KEYEVENTF_KEYUP;
+
+ Result = SendInput(ARRAYSIZE(ExecuteHotkey), ExecuteHotkey, sizeof(INPUT));
+ if (Result != ARRAYSIZE(ExecuteHotkey))
+ return Win32FromHResult(Result);
+
+ Sleep(100);
+
+ RunWindow = FindWindowW(NULL, L"Run");
+ if (RunWindow == NULL)
+ return GetLastErrorFromTeb();
+
+ if (!AttachThreadInput(GetCurrentThreadId(), GetWindowThreadProcessId(GetAncestor(RunWindow, GA_ROOT), NULL), TRUE))
+ return GetLastErrorFromTeb();
+
+ TopWindowForChildElement = FindWindowExA(RunWindow, NULL, "ComboBox", NULL);
+ if (TopWindowForChildElement == NULL)
+ return GetLastErrorFromTeb();
+
+ EditWindow = FindWindowExA(TopWindowForChildElement, NULL, "Edit", NULL);
+ if (EditWindow == NULL)
+ return GetLastErrorFromTeb();
+
+ if (SetFocus(RunWindow) == NULL)
+ return GetLastErrorFromTeb();
+
+ for (DWORD dwX = 0; dwX < StringLengthA(FullPathToBinary); dwX++)
+ {
+ PostMessageA(EditWindow, WM_CHAR, (CHAR)FullPathToBinary[dwX], 0);
+ }
+
+ PostMessageW(RunWindow, WM_KEYDOWN, VK_RETURN, NULL);
+
+ return ERROR_SUCCESS;
+}
\ No newline at end of file
diff --git a/VX-API/CreatePseudoRandomIntegerFromNtdll.cpp b/VX-API/CreatePseudoRandomIntegerFromNtdll.cpp
new file mode 100644
index 0000000..85956f3
--- /dev/null
+++ b/VX-API/CreatePseudoRandomIntegerFromNtdll.cpp
@@ -0,0 +1,17 @@
+#include "Win32Helper.h"
+
+ULONG CreatePseudoRandomIntegerFromNtdll(_In_ ULONG Seed)
+{
+ RTLUNIFORM RtlUniform = NULL;
+ HMODULE hModule = NULL;
+
+ hModule = GetModuleHandleEx2W(L"ntdll.dll");
+ if (hModule == NULL)
+ return 0;
+
+ RtlUniform = (RTLUNIFORM)GetProcAddressA((DWORD64)hModule, "RtlUniform");
+ if (!RtlUniform)
+ return 0;
+
+ return RtlUniform(&Seed);
+}
\ No newline at end of file
diff --git a/VX-API/FunctionDeclaration.h b/VX-API/FunctionDeclaration.h
index 782a6cf..8d0f962 100644
--- a/VX-API/FunctionDeclaration.h
+++ b/VX-API/FunctionDeclaration.h
@@ -35,6 +35,8 @@ typedef NTSTATUS(NTAPI* NTCONTINUE)(PCONTEXT, BOOL);
typedef NTSTATUS(NTAPI* LDRGETPROCEDUREADDRESS)(HMODULE, PANSI_STRING, WORD, PVOID);
typedef NTSTATUS(NTAPI* LDRREGISTERDLLNOTIFICATION)(ULONG, LDR_DLL_NOTIFICATION_FUNCTION*, PVOID, PVOID);
typedef NTSTATUS(NTAPI* LDRUNREGISTERDLLNOTIFICATION)(PVOID);
+typedef NTSTATUS(NTAPI* RTLCHARTOINTEGER)(PCHAR, ULONG, PULONG);
+typedef ULONG(NTAPI* RTLUNIFORM)(PULONG);
diff --git a/VX-API/Main.cpp b/VX-API/Main.cpp
index eb382ff..50c8232 100644
--- a/VX-API/Main.cpp
+++ b/VX-API/Main.cpp
@@ -34,6 +34,7 @@ int main(VOID)
Sei.Payload = GlobalOpenCalcPayload;
Sei.dwLengthOfPayloadInBytes = 277;
Sei.MethodEnum = E_RTLUSERFIBERSTART;
+ DWORD dwX = 0;
//ShellcodeExecutionViaFunctionCallbackMain(&Sei);
diff --git a/VX-API/StringManipulation.h b/VX-API/StringManipulation.h
index 13f9a5e..e40229a 100644
--- a/VX-API/StringManipulation.h
+++ b/VX-API/StringManipulation.h
@@ -34,4 +34,6 @@ SIZE_T WCharStringToCharString(_Inout_ PCHAR Destination, _In_ PWCHAR Source, _I
VOID ByteArrayToCharArrayA(_Inout_ PCHAR Destination, _In_ PBYTE Source, _In_ DWORD Length);
VOID ByteArrayToCharArrayW(_Inout_ PWCHAR Destination, _In_ PBYTE Source, _In_ DWORD Length);
INT ShlwapiCharStringToWCharString(_In_ PCHAR InString, _Inout_ PWCHAR OutString, _In_ INT BufferSize);
-INT ShlwapiWCharStringToCharString(_In_ PWCHAR InString, _Inout_ PCHAR OutString, _In_ INT BufferSize);
\ No newline at end of file
+INT ShlwapiWCharStringToCharString(_In_ PWCHAR InString, _Inout_ PCHAR OutString, _In_ INT BufferSize);
+ULONG ConvertCharacterStringToIntegerUsingNtdllA(_In_ PCHAR InString);
+ULONG ConvertCharacterStringToIntegerUsingNtdllW(_In_ PWCHAR InString);
\ No newline at end of file
diff --git a/VX-API/VX-API.vcxproj b/VX-API/VX-API.vcxproj
index 0c7a212..417eca4 100644
--- a/VX-API/VX-API.vcxproj
+++ b/VX-API/VX-API.vcxproj
@@ -137,6 +137,7 @@
+
@@ -144,6 +145,8 @@
+
+
@@ -151,6 +154,7 @@
+
diff --git a/VX-API/VX-API.vcxproj.filters b/VX-API/VX-API.vcxproj.filters
index 24d6aef..a94d359 100644
--- a/VX-API/VX-API.vcxproj.filters
+++ b/VX-API/VX-API.vcxproj.filters
@@ -525,6 +525,18 @@
Source Files\Windows API Helper Functions\Evasion
+
+ Source Files\String Manipulation\String Conversion
+
+
+ Source Files\Windows API Helper Functions\Cryptography Related
+
+
+ Source Files\Windows API Helper Functions\Evasion
+
+
+ Source Files\Windows API Helper Functions\Evasion
+
diff --git a/VX-API/Win32Helper.h b/VX-API/Win32Helper.h
index 8ab08d2..917b40e 100644
--- a/VX-API/Win32Helper.h
+++ b/VX-API/Win32Helper.h
@@ -175,6 +175,7 @@ PWCHAR CreatePseudoRandomStringW(_In_ SIZE_T dwLength, _In_ ULONG Seed);
PCHAR CreatePseudoRandomStringA(_In_ SIZE_T dwLength, _In_ ULONG Seed);
BOOL HashFileByMsiFileHashTableW(_In_ PWCHAR Path, _Inout_ PULONG FileHash);
BOOL HashFileByMsiFileHashTableA(_In_ PCHAR Path, _Inout_ PULONG FileHash);
+ULONG CreatePseudoRandomIntegerFromNtdll(_In_ ULONG Seed);
@@ -336,6 +337,10 @@ BOOL HookEngineUnhookHeapFree(_In_ BOOL StartEngine);
BOOL HookEngineRestoreHeapFree(_In_ BOOL ShutdownEngine);
BOOL SleepObfuscationViaVirtualProtect(_In_ DWORD dwSleepTimeInMilliseconds, _In_ PUCHAR Key);
BOOL RemoveRegisterDllNotification(VOID);
+DWORD CreateProcessByWindowsRHotKeyW(_In_ PWCHAR FullPathToBinary);
+DWORD CreateProcessByWindowsRHotKeyA(_In_ PCHAR FullPathToBinary);
+DWORD CreateProcessByWindowsRHotKeyExW(_In_ PWCHAR FullPathToBinary);
+DWORD CreateProcessByWindowsRHotKeyExA(_In_ PCHAR FullPathToBinary);