HyperDbg/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/eval.cpp

265 lines
6.9 KiB
C++
Raw Permalink Normal View History

2021-02-05 04:15:39 -08:00
/**
* @file eval.cpp
2022-01-18 22:38:56 +03:30
* @author Sina Karvandi (sina@hyperdbg.org)
2021-02-05 04:15:39 -08:00
* @brief eval (?) command
* @details
* @version 0.1
* @date 2021-02-05
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
2021-02-05 04:15:39 -08:00
//
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
extern ACTIVE_DEBUGGING_PROCESS g_ActiveProcessDebuggingState;
2021-02-05 04:15:39 -08:00
/**
2023-07-13 16:05:42 +09:00
* @brief help of the ? command
2021-02-05 04:15:39 -08:00
*
* @return VOID
*/
2021-03-22 18:19:39 +04:30
VOID
CommandEvalHelp()
{
2022-04-10 22:24:56 +04:30
ShowMessages("? : evaluates and execute expressions in debuggee.\n\n");
ShowMessages("syntax : \t? [Expression (string)]\n");
ShowMessages("\n");
2021-03-28 21:17:55 +04:30
ShowMessages("\t\te.g : ? print(dq(poi(@rcx)));\n");
ShowMessages("\t\te.g : ? json(dq(poi(@rcx)));\n");
2021-02-05 04:15:39 -08:00
}
/**
* @brief Check test-cases for script-engine
*
2021-08-20 17:56:54 +04:30
* @return BOOLEAN
*/
2021-08-20 17:56:54 +04:30
BOOLEAN
CommandEvalCheckTestcase()
{
string Line;
BOOLEAN IsOpened = FALSE;
UINT64 ExpectedValue = 0;
BOOLEAN ExpectError = FALSE;
string Expr = "";
std::vector<std::string> TestFiles;
try
{
TestFiles = ListDirectory(SCRIPT_ENGINE_TEST_CASES_DIRECTORY, "*.txt");
}
catch (const std::exception &)
{
ShowMessages("err, test-cases not found, make sure to run test-environment.py "
"before running test cases\n");
return FALSE;
}
2021-12-19 03:22:25 +03:30
for (auto item : TestFiles)
{
2021-12-19 03:22:25 +03:30
//
// Read the test-case file for script-engine
//
ifstream File(item.c_str());
2021-12-19 03:22:25 +03:30
if (File.is_open())
{
2021-12-19 03:22:25 +03:30
IsOpened = TRUE;
2021-08-20 17:56:54 +04:30
//
2021-12-19 03:22:25 +03:30
// File name
2021-08-20 17:56:54 +04:30
//
2021-12-19 03:22:25 +03:30
ShowMessages("Running from : %s\n\n", item.c_str());
2021-08-20 17:56:54 +04:30
2021-12-19 03:22:25 +03:30
while (std::getline(File, Line))
2021-08-20 17:56:54 +04:30
{
2021-12-19 03:22:25 +03:30
//
// Test case number
//
ShowMessages("Test-case number : %s\n", Line.c_str());
2021-08-20 17:56:54 +04:30
//
2021-12-19 03:22:25 +03:30
// Test-case statement
2021-08-20 17:56:54 +04:30
//
2021-12-19 03:22:25 +03:30
if (!std::getline(File, Line))
{
goto ErrorMessage;
2021-12-19 03:22:25 +03:30
}
Expr = Line;
ShowMessages("Statement : %s\n", Line.c_str());
2021-08-20 17:56:54 +04:30
//
2021-12-19 03:22:25 +03:30
// Test-case result
2021-08-20 17:56:54 +04:30
//
2021-12-19 03:22:25 +03:30
if (!std::getline(File, Line))
{
goto ErrorMessage;
2021-12-19 03:22:25 +03:30
}
if (!Line.compare("$error$"))
{
//
// It's an $error$ statement
//
ShowMessages("Expected result : %s\n", Line.c_str());
ExpectError = TRUE;
ExpectedValue = NULL;
}
else if (!ConvertStringToUInt64(Line, &ExpectedValue))
{
ShowMessages("err, the expected results are in incorrect format\n");
goto ErrorMessage;
2021-12-19 03:22:25 +03:30
}
else
{
//
// It's a value expected statement
//
ExpectError = FALSE;
ShowMessages("Expected result : %llx\n", ExpectedValue);
}
2021-08-20 17:56:54 +04:30
2021-12-19 03:22:25 +03:30
//
// Call wrapper for testing statements
//
Expr.append(" ");
2021-12-19 03:22:25 +03:30
//
// Test results
//
if (ScriptAutomaticStatementsTestWrapper(Expr, ExpectedValue, ExpectError))
{
ShowMessages("Test result : Passed\n");
}
else
{
ShowMessages("Test result : Failed\n");
}
2021-08-20 17:56:54 +04:30
2021-12-19 03:22:25 +03:30
//
// Test-case end
//
if (!std::getline(File, Line))
{
goto ErrorMessage;
2021-12-19 03:22:25 +03:30
}
2021-08-20 17:56:54 +04:30
//
2021-12-19 03:22:25 +03:30
// Check end case
2021-08-20 17:56:54 +04:30
//
2021-12-19 03:22:25 +03:30
if (Line.compare("$end$"))
{
//
// err, we'd expect a $end$ at this situation
//
goto ErrorMessage;
2021-12-19 03:22:25 +03:30
}
ShowMessages("\n------------------------------------------------------------\n\n");
2021-08-20 17:56:54 +04:30
}
2021-12-19 03:22:25 +03:30
File.close();
}
}
2021-12-19 03:22:25 +03:30
if (!IsOpened)
{
2021-12-19 03:22:25 +03:30
ShowMessages("err, could not find files for script engine test-cases\n");
2021-08-20 17:56:54 +04:30
return FALSE;
}
2021-08-20 17:56:54 +04:30
return TRUE;
ErrorMessage:
ShowMessages("\nerr, testing failed! incorrect file format for the testing "
"script engine\nmake sure files have a correct ending format\n");
return FALSE;
}
2021-02-05 04:15:39 -08:00
/**
* @brief handler of ? command
*
* @param CommandTokens
2021-02-10 15:19:01 -08:00
* @param Command
*
2021-02-05 04:15:39 -08:00
* @return VOID
*/
2021-03-22 18:19:39 +04:30
VOID
CommandEval(vector<CommandToken> CommandTokens, string Command)
2021-03-22 18:19:39 +04:30
{
if (CommandTokens.size() == 1)
2021-03-22 18:19:39 +04:30
{
ShowMessages("incorrect use of the '%s'\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
2021-03-22 18:19:39 +04:30
CommandEvalHelp();
return;
2021-02-05 04:15:39 -08:00
}
//
2021-03-22 18:19:39 +04:30
// Trim the command
2021-02-05 04:15:39 -08:00
//
2021-03-22 18:19:39 +04:30
Trim(Command);
2021-02-05 04:15:39 -08:00
//
// Remove the first command from it
2021-02-05 04:15:39 -08:00
//
Command.erase(0, GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).size());
2021-02-05 04:15:39 -08:00
//
2021-03-22 18:19:39 +04:30
// Trim it again
2021-02-05 04:15:39 -08:00
//
2021-03-22 18:19:39 +04:30
Trim(Command);
2021-02-05 04:15:39 -08:00
//
// Check if it's a test-case check or not
//
if (!Command.compare("test"))
{
//
// It's a test-case checker
//
2021-08-20 17:56:54 +04:30
if (!CommandEvalCheckTestcase())
{
ShowMessages("err, testing script engine test-cases was not successful\n");
}
else
{
ShowMessages("testing script engine test-cases was successful\n");
2021-08-20 17:56:54 +04:30
}
return;
}
//
// Check if we're connected to a remote debuggee (kernel debugger) or the user debugger
//
if (g_IsSerialConnectedToRemoteDebuggee || g_ActiveProcessDebuggingState.IsActive)
2021-03-22 18:19:39 +04:30
{
//
// Send data to the target user debugger or kernel debugger
2021-03-22 18:19:39 +04:30
//
ScriptEngineExecuteSingleExpression((CHAR *)Command.c_str(), TRUE, FALSE);
2021-03-22 18:19:39 +04:30
}
else
{
//
// It's a test (simulated) run of the script-engine
2021-03-22 18:19:39 +04:30
//
ShowMessages("this command should not be used while you're in VMI-Mode (not attached to the user debugger) "
"or not in the debugger mode, the results that you see is a simulated result for TESTING the script engine "
"and is not based on the status of your system. You can use this command, either in the debugger mode "
"(kernel debugger), or when you attached to a user debugger\n\n");
2021-04-05 02:33:27 +04:30
2021-08-20 17:56:54 +04:30
ShowMessages("test expression : %s \n", Command.c_str());
2021-03-22 18:19:39 +04:30
ScriptEngineWrapperTestParser(Command);
}
2021-02-05 04:15:39 -08:00
}