mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-11-07 06:59:05 +00:00
The remaining std::stoi() call sites in the user-mode helpers throw on malformed and out-of-range input. None of the callers catch, and there is no top-level handler, so a bad command argument terminates the process instead of being rejected with an error message. common/common.cpp: - IsNumber() tested against the character set "[0123456789]", so the two square brackets were accepted as digits. It is used as the guard in front of stoi() by several callers, which turns the mistake into a crash: "[1]" passes validation and then throws std::invalid_argument. Removed the brackets from the set. - ValidateIP() called stoi() on every octet. Together with the above, ".connect [1].2.3.4 50000" aborted the process; so did an octet long enough to overflow int, e.g. ".connect 99999999999.1.1.1". Replaced by a strtoul() range check, which saturates instead of throwing. - CheckAddressCanonicality() compared with a strict "<" against the start of the higher-half canonical range, so the boundary address itself (0xFFFF800000000000 at a 48-bit VA width) was reported as user-mode. CheckAccessValidityAndSafety() would then probe a kernel address from user mode rather than refusing it. - ListDirectory() called FindNextFileA() before consuming the match that FindFirstFileA() had already stored in FindData, so the first file of every listing was silently dropped. Turned into a do/while. - isxdigit()/isdigit()/isspace() were handed a plain char; passing a negative value to the <ctype.h> functions is undefined behavior and trips the MSVC debug CRT on any input with a byte above 0x7f. Cast to UCHAR at the four call sites. The same crash class at the call sites that use stoi() directly on user input, all replaced with strtoul() so the existing range checks reject the value instead of an exception escaping: - connect.cpp (x2) and listen.cpp: TCP port validation. - debug.cpp: serial baud rate. Verified by extracting the affected functions from common.cpp and running them under ASan/UBSan over a 316-probe corpus, before and after. The baseline aborts with SIGABRT on three inputs; afterwards every probe returns a defined result and exactly the seven intended lines differ. The four modified files were also compiled with the project's own Linux CMake build to confirm they build clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3C1DuhHtqK64eEkHjKCHM
198 lines
4.5 KiB
C++
198 lines
4.5 KiB
C++
/**
|
|
* @file connect.cpp
|
|
* @author Sina Karvandi (sina@hyperdbg.org)
|
|
* @brief .connect command
|
|
* @details
|
|
* @version 0.1
|
|
* @date 2020-05-27
|
|
*
|
|
* @copyright This project is released under the GNU Public License v3.
|
|
*
|
|
*/
|
|
#include "pch.h"
|
|
|
|
//
|
|
// Global Variables
|
|
//
|
|
extern BOOLEAN g_IsConnectedToHyperDbgLocally;
|
|
extern BOOLEAN g_IsConnectedToRemoteDebuggee;
|
|
extern BOOLEAN g_IsConnectedToRemoteDebugger;
|
|
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
|
|
extern BOOLEAN g_IsSerialConnectedToRemoteDebugger;
|
|
extern string g_ServerPort;
|
|
extern string g_ServerIp;
|
|
|
|
/**
|
|
* @brief help of the .connect command
|
|
*
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
CommandConnectHelp()
|
|
{
|
|
ShowMessages(".connect : connects to a remote or local machine to start "
|
|
"debugging.\n\n");
|
|
|
|
ShowMessages("syntax : \t.connect [local]\n");
|
|
ShowMessages("syntax : \t.connect [Ip (string)] [Port (decimal)]\n");
|
|
|
|
ShowMessages("\n");
|
|
ShowMessages("\t\te.g : .connect local\n");
|
|
ShowMessages("\t\te.g : .connect 192.168.1.5 50000\n");
|
|
}
|
|
|
|
/**
|
|
* @brief Connect to local debugger
|
|
*
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
ConnectLocalDebugger()
|
|
{
|
|
g_IsConnectedToHyperDbgLocally = TRUE;
|
|
}
|
|
|
|
/**
|
|
* @brief Connect to remote debugger
|
|
*
|
|
* @return BOOLEAN
|
|
*/
|
|
BOOLEAN
|
|
ConnectRemoteDebugger(const CHAR * Ip, const CHAR * Port)
|
|
{
|
|
//
|
|
// Validate IP and Port
|
|
|
|
if (!ValidateIP(Ip))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (Port != NULL)
|
|
{
|
|
if (!IsNumber(Port) || strtoul(Port, NULL, 10) > 65535)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// connect to remote debugger
|
|
//
|
|
g_ServerIp = Ip;
|
|
g_ServerPort = Port;
|
|
RemoteConnectionConnect(Ip, Port);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// connect to remote debugger (default port)
|
|
//
|
|
g_ServerIp = Ip;
|
|
g_ServerPort = DEFAULT_PORT;
|
|
RemoteConnectionConnect(Ip, DEFAULT_PORT);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* @brief .connect command handler
|
|
*
|
|
* @param CommandTokens
|
|
* @param Command
|
|
*
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
CommandConnect(vector<CommandToken> CommandTokens, string Command)
|
|
{
|
|
string Ip;
|
|
string Port;
|
|
|
|
if (g_IsConnectedToHyperDbgLocally || g_IsConnectedToRemoteDebuggee ||
|
|
g_IsConnectedToRemoteDebugger)
|
|
{
|
|
ShowMessages("you're connected to a debugger, please use '.disconnect' "
|
|
"command\n");
|
|
return;
|
|
}
|
|
|
|
if (g_IsSerialConnectedToRemoteDebuggee ||
|
|
g_IsSerialConnectedToRemoteDebugger)
|
|
{
|
|
ShowMessages("you're connected to a an instance of HyperDbg, please use "
|
|
"'.debug close' command\n");
|
|
return;
|
|
}
|
|
|
|
if (CommandTokens.size() == 1)
|
|
{
|
|
//
|
|
// Means that user entered just a connect so we have to
|
|
// ask to connect to what ?
|
|
//
|
|
ShowMessages("incorrect use of the '%s'\n\n",
|
|
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
|
|
CommandConnectHelp();
|
|
return;
|
|
}
|
|
else if (CompareLowerCaseStrings(CommandTokens.at(1), "local") && CommandTokens.size() == 2)
|
|
{
|
|
//
|
|
// connect to local debugger
|
|
//
|
|
ShowMessages("local debugging (vmi-mode)\n");
|
|
|
|
ConnectLocalDebugger();
|
|
|
|
return;
|
|
}
|
|
else if (CommandTokens.size() == 3 || CommandTokens.size() == 2)
|
|
{
|
|
Ip = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(1));
|
|
|
|
if (CommandTokens.size() == 3)
|
|
{
|
|
Port = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2));
|
|
}
|
|
|
|
//
|
|
// means that probably wants to connect to a remote
|
|
// system, let's first check the if the parameters are
|
|
// valid
|
|
//
|
|
if (!ValidateIP(Ip))
|
|
{
|
|
ShowMessages("incorrect ip address\n");
|
|
return;
|
|
}
|
|
|
|
if (CommandTokens.size() == 3)
|
|
{
|
|
if (!IsNumber(Port) || strtoul(Port.c_str(), NULL, 10) > 65535)
|
|
{
|
|
ShowMessages("incorrect port\n");
|
|
return;
|
|
}
|
|
|
|
//
|
|
// connect to remote debugger
|
|
//
|
|
ConnectRemoteDebugger(Ip.c_str(), Port.c_str());
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// connect to remote debugger (default port)
|
|
//
|
|
ConnectRemoteDebugger(Ip.c_str(), NULL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ShowMessages("incorrect use of the '%s'\n\n",
|
|
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
|
|
CommandConnectHelp();
|
|
return;
|
|
}
|
|
}
|