mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-10 01:29:59 +00:00
support multiline commands in .script command
This commit is contained in:
parent
c09d4b2989
commit
5544fe30ae
5 changed files with 225 additions and 121 deletions
|
|
@ -30,6 +30,49 @@ CommandScriptHelp()
|
|||
ShowMessages("syntax : \.script [FilePath]\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run the command
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CommandScriptRunCommand(char * LineContent)
|
||||
{
|
||||
int CommandExecutionResult = 0;
|
||||
|
||||
//
|
||||
// Check if the it's a command or not
|
||||
//
|
||||
InterpreterRemoveComments(LineContent);
|
||||
|
||||
if (IsEmptyString(LineContent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Show current running command
|
||||
//
|
||||
HyperdbgShowSignature();
|
||||
|
||||
ShowMessages("%s\n", LineContent);
|
||||
|
||||
CommandExecutionResult = HyperdbgInterpreter(LineContent);
|
||||
|
||||
ShowMessages("\n");
|
||||
|
||||
//
|
||||
// if the debugger encounters an exit state then the return will be 1
|
||||
//
|
||||
if (CommandExecutionResult == 1)
|
||||
{
|
||||
//
|
||||
// Exit from the debugger
|
||||
//
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief .script command handler
|
||||
*
|
||||
|
|
@ -41,8 +84,9 @@ VOID
|
|||
CommandScript(vector<string> SplittedCommand, string Command)
|
||||
{
|
||||
std::string Line;
|
||||
BOOLEAN IsOpened = FALSE;
|
||||
int CommandExecutionResult = 0;
|
||||
BOOLEAN IsOpened = FALSE;
|
||||
bool Reset = false;
|
||||
string CommandToExecute = "";
|
||||
|
||||
if (SplittedCommand.size() == 1)
|
||||
{
|
||||
|
|
@ -80,38 +124,73 @@ CommandScript(vector<string> SplittedCommand, string Command)
|
|||
//
|
||||
g_ExecutingScript = TRUE;
|
||||
|
||||
//
|
||||
// Reset multiline command
|
||||
//
|
||||
Reset = true;
|
||||
|
||||
while (std::getline(File, Line))
|
||||
{
|
||||
char * LineContent = (char *)Line.c_str();
|
||||
//
|
||||
// Check if the it's a command or not
|
||||
// Check for multiline commands
|
||||
//
|
||||
InterpreterRemoveComments(LineContent);
|
||||
|
||||
if (IsEmptyString(LineContent))
|
||||
if (HyperDbgCheckMultilineCommand(Line, Reset))
|
||||
{
|
||||
//
|
||||
// if the reset is true, we should make the saving buffer empty
|
||||
//
|
||||
if (Reset)
|
||||
{
|
||||
CommandToExecute.clear();
|
||||
}
|
||||
|
||||
//
|
||||
// The command is expected to be continued
|
||||
//
|
||||
Reset = false;
|
||||
|
||||
//
|
||||
// Append to the previous command
|
||||
//
|
||||
CommandToExecute += Line + "\n";
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Show current running command
|
||||
//
|
||||
ShowMessages("\n%s\n", LineContent);
|
||||
|
||||
CommandExecutionResult = HyperdbgInterpreter(LineContent);
|
||||
|
||||
ShowMessages("\n");
|
||||
|
||||
//
|
||||
// if the debugger encounters an exit state then the return will be 1
|
||||
//
|
||||
if (CommandExecutionResult == 1)
|
||||
else
|
||||
{
|
||||
//
|
||||
// Exit from the debugger
|
||||
// Reset for the next commands round
|
||||
//
|
||||
exit(0);
|
||||
Reset = true;
|
||||
|
||||
//
|
||||
// Append this line too
|
||||
//
|
||||
CommandToExecute += Line;
|
||||
}
|
||||
|
||||
//
|
||||
// Run the command
|
||||
//
|
||||
CommandScriptRunCommand((char *)CommandToExecute.c_str());
|
||||
|
||||
//
|
||||
// Clear the command
|
||||
//
|
||||
CommandToExecute.clear();
|
||||
}
|
||||
|
||||
//
|
||||
// Check for some probably not ended commands
|
||||
//
|
||||
if (!CommandToExecute.empty())
|
||||
{
|
||||
CommandScriptRunCommand((char *)CommandToExecute.c_str());
|
||||
|
||||
//
|
||||
// Clear the command
|
||||
//
|
||||
CommandToExecute.clear();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -28,8 +28,11 @@ extern BOOLEAN g_IsConnectedToRemoteDebuggee;
|
|||
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
|
||||
extern BOOLEAN g_IsDebuggeeRunning;
|
||||
extern BOOLEAN g_BreakPrintingOutput;
|
||||
extern BOOLEAN g_IsInterpreterOnString;
|
||||
extern BOOLEAN g_IsInterpreterPreviousCharacterABackSlash;
|
||||
|
||||
extern ULONG g_CurrentRemoteCore;
|
||||
extern UINT32 g_InterpreterCountOfOpenCurlyBrackets;
|
||||
extern ULONG g_CurrentRemoteCore;
|
||||
|
||||
extern string g_ServerPort;
|
||||
extern string g_ServerIp;
|
||||
|
|
@ -330,6 +333,98 @@ HyperdbgShowSignature()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check for multi-line commands
|
||||
*
|
||||
* @param CurrentCommand
|
||||
* @param Reset
|
||||
* @return bool return true if the command needs extra input, otherwise
|
||||
* return false
|
||||
*/
|
||||
bool
|
||||
HyperDbgCheckMultilineCommand(std::string & CurrentCommand, bool Reset)
|
||||
{
|
||||
if (Reset)
|
||||
{
|
||||
g_IsInterpreterOnString = FALSE;
|
||||
g_IsInterpreterPreviousCharacterABackSlash = FALSE;
|
||||
g_InterpreterCountOfOpenCurlyBrackets = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < CurrentCommand.length(); i++)
|
||||
{
|
||||
switch (CurrentCommand.at(i))
|
||||
{
|
||||
case '"':
|
||||
|
||||
if (g_IsInterpreterPreviousCharacterABackSlash)
|
||||
{
|
||||
g_IsInterpreterPreviousCharacterABackSlash = FALSE;
|
||||
break; // it's an escaped \" double-quote
|
||||
}
|
||||
|
||||
if (g_IsInterpreterOnString)
|
||||
g_IsInterpreterOnString = FALSE;
|
||||
else
|
||||
g_IsInterpreterOnString = TRUE;
|
||||
|
||||
break;
|
||||
|
||||
case '{':
|
||||
|
||||
if (g_IsInterpreterPreviousCharacterABackSlash)
|
||||
g_IsInterpreterPreviousCharacterABackSlash = FALSE;
|
||||
|
||||
if (!g_IsInterpreterOnString)
|
||||
g_InterpreterCountOfOpenCurlyBrackets++;
|
||||
|
||||
break;
|
||||
|
||||
case '}':
|
||||
|
||||
if (g_IsInterpreterPreviousCharacterABackSlash)
|
||||
g_IsInterpreterPreviousCharacterABackSlash = FALSE;
|
||||
|
||||
if (!g_IsInterpreterOnString && g_InterpreterCountOfOpenCurlyBrackets > 0)
|
||||
g_InterpreterCountOfOpenCurlyBrackets--;
|
||||
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
|
||||
if (g_IsInterpreterPreviousCharacterABackSlash)
|
||||
g_IsInterpreterPreviousCharacterABackSlash = FALSE; // it's not a escape character (two backslashes \\ )
|
||||
else
|
||||
g_IsInterpreterPreviousCharacterABackSlash = TRUE;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (g_IsInterpreterPreviousCharacterABackSlash)
|
||||
g_IsInterpreterPreviousCharacterABackSlash = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_IsInterpreterOnString == FALSE && g_InterpreterCountOfOpenCurlyBrackets == 0)
|
||||
{
|
||||
//
|
||||
// either the command is finished or it's a single
|
||||
// line command
|
||||
//
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// There still other lines, this command is incomplete
|
||||
//
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Some of commands like stepping commands (i, p, t) and etc.
|
||||
* need to be repeated when the user press enter, this function shows
|
||||
|
|
|
|||
|
|
@ -29,4 +29,5 @@ __declspec(dllexport) void HyperdbgSetTextMessageCallback(Callback handler);
|
|||
__declspec(dllexport) int HyperdbgInterpreter(char * Command);
|
||||
__declspec(dllexport) void HyperdbgShowSignature();
|
||||
__declspec(dllexport) bool HyperdbgContinuePreviousCommand();
|
||||
__declspec(dllexport) bool HyperDbgCheckMultilineCommand(std::string & CurrentCommand, bool Reset);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,25 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Interpreter Variables //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief shows whether the interpreter is currently on a string or not
|
||||
*/
|
||||
BOOLEAN g_IsInterpreterOnString = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Is interpreter ecountered a back slash at previous run
|
||||
*/
|
||||
BOOLEAN g_IsInterpreterPreviousCharacterABackSlash = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Keeps the trace of curly brackets in the interpreter
|
||||
*/
|
||||
UINT32 g_InterpreterCountOfOpenCurlyBrackets = 0;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Remote and Local Connection //
|
||||
//////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -21,13 +21,6 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
//
|
||||
// Global variables
|
||||
//
|
||||
bool IsOnString = false;
|
||||
bool IsPreviousCharacterABackSlash = false;
|
||||
int CountOfOpenCurlyBrackets = 0;
|
||||
|
||||
//
|
||||
// Header file of HPRDBGCTRL
|
||||
// Imports
|
||||
|
|
@ -41,93 +34,10 @@ __declspec(dllimport) int HyperdbgStopDriver();
|
|||
__declspec(dllimport) int HyperdbgInterpreter(char * Command);
|
||||
__declspec(dllimport) void HyperdbgShowSignature();
|
||||
__declspec(dllimport) bool HyperdbgContinuePreviousCommand();
|
||||
__declspec(dllimport) bool HyperDbgCheckMultilineCommand(std::string & CurrentCommand, bool Reset);
|
||||
__declspec(dllimport) void HyperdbgSetTextMessageCallback(Callback handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check for multi-line commands
|
||||
*
|
||||
* @param CurrentCommand
|
||||
* @return bool return true if the command needs extra input, otherwise
|
||||
* return false
|
||||
*/
|
||||
bool
|
||||
CheckMultilineCommand(std::string CurrentCommand)
|
||||
{
|
||||
for (size_t i = 0; i < CurrentCommand.length(); i++)
|
||||
{
|
||||
switch (CurrentCommand.at(i))
|
||||
{
|
||||
case '"':
|
||||
|
||||
if (IsPreviousCharacterABackSlash)
|
||||
{
|
||||
IsPreviousCharacterABackSlash = false;
|
||||
break; // it's an escaped \" double-quote
|
||||
}
|
||||
|
||||
if (IsOnString)
|
||||
IsOnString = false;
|
||||
else
|
||||
IsOnString = true;
|
||||
|
||||
break;
|
||||
|
||||
case '{':
|
||||
|
||||
if (IsPreviousCharacterABackSlash)
|
||||
IsPreviousCharacterABackSlash = false;
|
||||
|
||||
if (!IsOnString)
|
||||
CountOfOpenCurlyBrackets++;
|
||||
|
||||
break;
|
||||
|
||||
case '}':
|
||||
|
||||
if (IsPreviousCharacterABackSlash)
|
||||
IsPreviousCharacterABackSlash = false;
|
||||
|
||||
if (!IsOnString && CountOfOpenCurlyBrackets > 0)
|
||||
CountOfOpenCurlyBrackets--;
|
||||
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
|
||||
if (IsPreviousCharacterABackSlash)
|
||||
IsPreviousCharacterABackSlash = false; // it's not a escape character (two backslashes \\ )
|
||||
else
|
||||
IsPreviousCharacterABackSlash = true;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (IsPreviousCharacterABackSlash)
|
||||
IsPreviousCharacterABackSlash = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsOnString == FALSE && CountOfOpenCurlyBrackets == 0)
|
||||
{
|
||||
//
|
||||
// either the command is finished or it's a single
|
||||
// line command
|
||||
//
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// There still other lines, this command is incomplete
|
||||
//
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CLI main function
|
||||
*
|
||||
|
|
@ -140,6 +50,7 @@ main(int argc, char * argv[])
|
|||
{
|
||||
bool ExitFromDebugger = false;
|
||||
string PreviousCommand;
|
||||
bool Reset = false;
|
||||
|
||||
printf("HyperDbg Debugger [core version: v%s]\n", Version);
|
||||
printf("Please visit https://docs.hyperdbg.org for more information...\n");
|
||||
|
|
@ -172,10 +83,8 @@ main(int argc, char * argv[])
|
|||
{
|
||||
HyperdbgShowSignature();
|
||||
|
||||
string CurrentCommand = "";
|
||||
IsOnString = false;
|
||||
IsPreviousCharacterABackSlash = false;
|
||||
CountOfOpenCurlyBrackets = 0;
|
||||
string CurrentCommand = "";
|
||||
Reset = true;
|
||||
|
||||
GetMultiLinecCommand:
|
||||
|
||||
|
|
@ -197,16 +106,17 @@ main(int argc, char * argv[])
|
|||
//
|
||||
// Check for multi-line commands
|
||||
//
|
||||
if (CheckMultilineCommand(TempCommand) == true)
|
||||
if (HyperDbgCheckMultilineCommand(TempCommand, Reset) == true)
|
||||
{
|
||||
//
|
||||
// It's a multi-line command
|
||||
//
|
||||
Reset = false;
|
||||
|
||||
//
|
||||
// Save the command with a space separator
|
||||
//
|
||||
CurrentCommand += TempCommand + " ";
|
||||
CurrentCommand += TempCommand + "\n";
|
||||
|
||||
//
|
||||
// Show a small signature
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue