HyperDbg/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/script.cpp

294 lines
6.3 KiB
C++
Raw Permalink Normal View History

2020-07-03 15:16:14 -07:00
/**
* @file script.cpp
2022-01-18 22:38:56 +03:30
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief .script command
2020-07-03 15:16:14 -07:00
* @details
* @version 0.1
* @date 2020-07-03
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
2020-07-03 15:16:14 -07:00
using namespace std;
2020-08-28 04:03:12 -07:00
//
// Global Variables
//
extern BOOLEAN g_ExecutingScript;
2020-08-28 04:03:12 -07:00
/**
2023-07-13 16:05:42 +09:00
* @brief help of the .script command
*
* @return VOID
2020-08-28 04:03:12 -07:00
*/
2021-03-22 18:19:39 +04:30
VOID
CommandScriptHelp()
{
2022-04-10 22:24:56 +04:30
ShowMessages(".script : runs a HyperDbg script.\n\n");
2024-03-14 14:02:18 +09:00
ShowMessages("syntax : .script [FilePath (string)] [Args (string)]\n");
ShowMessages("\n");
2022-04-14 12:46:19 +04:30
ShowMessages("\t\te.g : .script C:\\scripts\\script.ds\n");
ShowMessages("\t\te.g : .script C:\\scripts\\script.ds 95 85 @rsp\n");
ShowMessages("\t\te.g : .script \"C:\\scripts\\hello world.ds\"\n");
ShowMessages("\t\te.g : .script \"C:\\scripts\\hello world.ds\" @rax\n");
ShowMessages("\t\te.g : .script \"C:\\scripts\\hello world.ds\" @rax @rcx+55 $pid\n");
ShowMessages("\t\te.g : .script \"C:\\scripts\\hello world.ds\" 12 55 @rip\n");
2020-07-03 15:16:14 -07:00
}
/**
* @brief Run the command
*
* @return VOID
*/
VOID
2022-02-02 23:46:29 +03:30
CommandScriptRunCommand(std::string Input, vector<string> PathAndArgs)
{
INT CommandExecutionResult = 0;
CHAR * LineContent = NULL;
INT i = 0;
2022-02-02 23:46:29 +03:30
//
// Replace the $arg*s
// This is not a good approach to replace between strings,
// but we let it work this way and in the future versions
// we'll integrate the command parsing in the debugger with
// the script engine's command parser
//
for (auto item : PathAndArgs)
{
string ToReplace = "$arg" + std::to_string(i);
i++;
ReplaceAll(Input, ToReplace, item);
}
//
// Convert script to char*
//
LineContent = (CHAR *)Input.c_str();
if (IsEmptyString(LineContent))
{
return;
}
//
// Show current running command
//
2022-07-15 14:52:07 -07:00
HyperDbgShowSignature();
ShowMessages("%s\n", LineContent);
2022-07-15 14:52:07 -07:00
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);
}
}
2020-08-28 04:03:12 -07:00
/**
* @brief Read file and run the script
*
* @return VOID
2020-08-28 04:03:12 -07:00
*/
2021-03-22 18:19:39 +04:30
VOID
2022-06-22 13:20:14 -07:00
HyperDbgScriptReadFileAndExecuteCommand(std::vector<std::string> & PathAndArgs)
2021-03-22 18:19:39 +04:30
{
std::string Line;
BOOLEAN IsOpened = FALSE;
BOOLEAN Reset = FALSE;
string CommandToExecute = "";
string PathOfScriptFile = "";
2021-12-05 01:56:36 +03:30
//
// Parse the script file,
// the first argument is the path
//
PathOfScriptFile = PathAndArgs.at(0);
ReplaceAll(PathOfScriptFile, "\"", "");
ifstream File(PathOfScriptFile);
2021-03-22 18:19:39 +04:30
if (File.is_open())
{
IsOpened = TRUE;
2020-07-03 15:16:14 -07:00
//
2021-03-22 18:19:39 +04:30
// Indicate that it's a script
2020-07-03 15:16:14 -07:00
//
2021-03-22 18:19:39 +04:30
g_ExecutingScript = TRUE;
//
// Reset multiline command
//
Reset = TRUE;
2021-03-22 18:19:39 +04:30
while (std::getline(File, Line))
{
//
// Check for multiline commands
//
2024-06-24 19:07:06 +09:00
if (CheckMultilineCommand((char *)Line.c_str(), 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;
}
else
{
//
// Reset for the next commands round
//
Reset = TRUE;
//
// Append this line too
//
CommandToExecute += Line;
}
2021-04-24 16:50:12 +04:30
//
// Run the command
2021-04-24 16:50:12 +04:30
//
2022-02-02 23:46:29 +03:30
CommandScriptRunCommand(CommandToExecute, PathAndArgs);
//
// Clear the command
//
CommandToExecute.clear();
}
2021-04-24 16:50:12 +04:30
//
// Check for some probably not ended commands
//
if (!CommandToExecute.empty())
{
2022-02-02 23:46:29 +03:30
CommandScriptRunCommand(CommandToExecute, PathAndArgs);
2021-03-22 18:19:39 +04:30
//
// Clear the command
2021-03-22 18:19:39 +04:30
//
CommandToExecute.clear();
2021-03-22 18:19:39 +04:30
}
2021-03-22 18:19:39 +04:30
//
// Indicate that script is finished
//
g_ExecutingScript = FALSE;
2021-03-22 18:19:39 +04:30
File.close();
}
2020-07-03 15:16:14 -07:00
2021-03-22 18:19:39 +04:30
if (!IsOpened)
{
ShowMessages("err, invalid file specified for the script\n");
2021-03-22 18:19:39 +04:30
}
2020-07-03 15:16:14 -07:00
}
2022-11-16 14:25:37 +09:00
/**
* @brief Parsing the command line options for scripts
2024-07-06 22:46:57 +09:00
* @param argc
* @param argv
2022-11-16 14:25:37 +09:00
*
2024-06-24 19:07:06 +09:00
* @return INT
2022-11-16 14:25:37 +09:00
*/
2024-06-24 19:07:06 +09:00
INT
2026-05-29 00:10:44 +02:00
HyperDbgScriptReadFileAndExecuteCommandline(INT argc, CHAR * argv[])
2022-11-16 14:25:37 +09:00
{
vector<string> Args;
//
// Convert it to the array
//
for (SIZE_T i = 2; i < argc; i++)
2022-11-16 14:25:37 +09:00
{
std::string TempStr(argv[i]);
Args.push_back(TempStr);
}
//
// Check if the target path and args for script is not empty
//
if (!Args.empty())
{
HyperDbgScriptReadFileAndExecuteCommand(Args);
printf("\n");
}
else
{
printf("err, invalid command line options passed to the HyperDbg!\n");
return FALSE;
}
return TRUE;
}
/**
* @brief .script command handler
*
* @param CommandTokens
* @param Command
* @return VOID
*/
VOID
CommandScript(vector<CommandToken> CommandTokens, string Command)
{
vector<string> PathAndArgs;
BOOLEAN IsFirstCommand = FALSE;
if (CommandTokens.size() == 1)
{
ShowMessages("please specify a file\n\n");
CommandScriptHelp();
return;
}
for (auto Section : CommandTokens)
{
if (!IsFirstCommand)
{
IsFirstCommand = TRUE;
continue;
}
//
// Add the path and the arguments
//
PathAndArgs.push_back(GetCaseSensitiveStringFromCommandToken(Section));
}
//
// Parse the file and the possible arguments
//
HyperDbgScriptReadFileAndExecuteCommand(PathAndArgs);
}