Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Process struct for use with the ScriptCompilationSystem in RED4ext #79

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions include/RED4ext/Process-inl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#pragma once
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the cpp file too.


#ifdef RED4EXT_STATIC_LIB
#include <RED4ext/Process.hpp>
#endif
#include <RED4ext/Relocation.hpp>
Comment on lines +5 to +6
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#endif
#include <RED4ext/Relocation.hpp>
#endif
#include <RED4ext/Relocation.hpp>


// This file has been generated by zoltan (https://github.com/jac3km4/zoltan)

#define Process_CloseHandles_Addr 0x2C23B30
#define Process_Execute_Addr 0x2C23D70
#define Process_Execute_0_Addr 0x2C23DD0
#define Process_GetExitCode_Addr 0x2C23B60
#define Process_Process_Addr 0x2C23AA0
#define Process_ReadFromPipe_Addr 0x2C23B90
#define Process_Terminate_Addr 0x2C24040
#define Process_WaitUntilCompleted_Addr 0x2C240B0
Comment on lines +8 to +17
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these to IDA script.


inline bool RED4ext::Process::CloseHandles()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
inline bool RED4ext::Process::CloseHandles()
RED4EXT_INLINE bool RED4ext::Process::CloseHandles()

Same for the others.

{
using Process_CloseHandles_t = bool (*)(RED4ext::Process*);
RED4ext::RelocFunc<Process_CloseHandles_t> call(Process_CloseHandles_Addr);
return call(this);
}

inline bool RED4ext::Process::Execute(const RED4ext::CString& a1, RED4ext::Process::FixedWString& a2,
const RED4ext::CString& a3, const RED4ext::Process::ExecutionFlags a4)
{
using Process_Execute_t = bool (*)(RED4ext::Process*, const RED4ext::CString&, RED4ext::Process::FixedWString&,
const RED4ext::CString&, const RED4ext::Process::ExecutionFlags);
RED4ext::RelocFunc<Process_Execute_t> call(Process_Execute_Addr);
return call(this, a1, a2, a3, a4);
}

inline bool RED4ext::Process::Execute(const RED4ext::CString& a1, RED4ext::Process::FixedWString& a2,
const RED4ext::Process::FixedWString& a3,
const RED4ext::Process::ExecutionFlags a4)
{
using Process_Execute_0_t = bool (*)(RED4ext::Process*, const RED4ext::CString&, RED4ext::Process::FixedWString&,
const RED4ext::Process::FixedWString&, const RED4ext::Process::ExecutionFlags);
RED4ext::RelocFunc<Process_Execute_0_t> call(Process_Execute_0_Addr);
return call(this, a1, a2, a3, a4);
}

inline uint64_t RED4ext::Process::GetExitCode()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
inline uint64_t RED4ext::Process::GetExitCode()
RED4EXT_INLINE DWORD RED4ext::Process::GetExitCode()

{
using Process_GetExitCode_t = uint64_t (*)(RED4ext::Process*);
RED4ext::RelocFunc<Process_GetExitCode_t> call(Process_GetExitCode_Addr);
return call(this);
}

inline void RED4ext::Process::ReadFromPipe(const RED4ext::Process::ReadFlags a1, const RED4ext::CString& a2,
RED4ext::CString& a3)
{
using Process_ReadFromPipe_t =
void (*)(RED4ext::Process*, const RED4ext::Process::ReadFlags, const RED4ext::CString&, RED4ext::CString&);
RED4ext::RelocFunc<Process_ReadFromPipe_t> call(Process_ReadFromPipe_Addr);
return call(this, a1, a2, a3);
}

inline bool RED4ext::Process::Terminate(const uint32_t a1, const bool a2)
{
using Process_Terminate_t = bool (*)(RED4ext::Process*, const uint32_t, const bool);
RED4ext::RelocFunc<Process_Terminate_t> call(Process_Terminate_Addr);
return call(this, a1, a2);
}

inline bool RED4ext::Process::WaitUntilCompleted(const uint32_t a1) const
{
using Process_WaitUntilCompleted_t = bool (*)(RED4ext::Process*, const uint32_t);
RED4ext::RelocFunc<Process_WaitUntilCompleted_t> call(Process_WaitUntilCompleted_Addr);
return call(this, a1);
}
118 changes: 118 additions & 0 deletions include/RED4ext/Process.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#pragma once

#include <RED4ext/CString.hpp>
#include <RED4ext/Common.hpp>
#include <cstdint>

namespace RED4ext
{
struct Process
{
static constexpr uint32_t DefaultTimeout = 60000;

struct FixedWString
{
uint32_t length;
uint32_t maxLength;
const wchar_t* str;
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be WString or WideString or CWideString? Capacity field suggests that this is a mutable string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right - it looks like this is used elsewhere too. I'll do some digging and see what I can find.


enum class ExecutionFlags : std::uint8_t
{
// unsets CREATE_NO_WINDOW
ShouldCreateWindow = 0x1,
// sets CREATE_BREAKAWAY_FROM_JOB | CREATE_SUSPENDED in Process Creation Flags
BreakawayAndSuspend = 0x2,
// unsets bInheritHandles
NoInheritHandles = 0x4
};

enum class ReadFlags : std::uint8_t
{
// open & read regardless of other options
Unk1 = 0x1,
// opens file from name provided and writes output
WriteToFile = 0x2,
// writes output to CString
GetCString = 0x4
};
Comment on lines +15 to +33
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remembered that we decided to use struct flags, e.g. https://github.com/WopsS/RED4ext.SDK/blob/master/include/RED4ext/RTTITypes.hpp#L117-L132, so please convert these a as well to be consistent.


/**
* @brief creates the read & write pipes, and handle information
*
* @param[in] aHandle The plugin's handle.
* @param[in] aPath The path to be added to the redscript compilation - can be a folder or a .reds file
*
* @return Returns true if the path was added is attached, false otherwise.
*
* @pattern 48 89 5C 24 08 57 48 83 EC 40 33 C0 C7 44 24 20 18 00 00 00 48 8D 91 08 20 00 00 48 89 81 00 20
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these pattern in the IDA script.

*/
Process();

/// @pattern 40 53 48 83 EC 20 48 8B D9 48 8B 89 08 20 00 00 FF 15 ? ? 4B 00 48 8B 8B 00 20 00 00 48 83 C4
bool CloseHandles();

/**
* @brief Assigns the process's error code to this->errorCode
*
* @return Returns the error code
*
* @pattern 40 53 48 83 EC 20 48 8D 99 28 20 00 00 48 8B 89 10 20 00 00 48 8B D3 FF 15 ? ? 4B 00 8B 03 48
*/
DWORD GetExitCode();

/// @pattern 40 55 56 57 41 56 B8 68 20 00 00 E8 ? ? E7 FF 48 2B E0 49 8B E9 49 8B F0 8B FA 4C 8B F1 F6 C2
void ReadFromPipe(const ReadFlags aFlags, const CString& aFilename, CString& aStdOut);

/**
* @brief Converts aWorkingDirectory to a FixedWString and calls Execute
*
* @param[in] aCommand The location of the executable
* @param[in] aArgs Arguments passed to the command
* @param[in] aWorkingDirectory The directory to execute the process from
* @param[in] aFlags Flags that alter the execution
*
* @return True if the process was started successfully
*
* @pattern 48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 40 48 8B FA 48 8B F1 48 8D 54 24 30 49 8B C9 49 8B D8
*/
bool Execute(const CString& aCommand, FixedWString& aArgs, const CString& aWorkingDirectory,
const ExecutionFlags aFlags);

/**
* @brief Begins the proccess
*
* @param[in] aCommand The location of the executable
* @param[in] aArgs Arguments passed to the command
* @param[in] aWorkingDirectory The directory to execute the process from
* @param[in] aFlags Flags that alter the execution
*
* @return True if the process was started successfully
*
* @pattern 48 89 5C 24 10 48 89 74 24 18 55 57 41 54 41 56 41 57 48 8D 6C 24 B0 48 81 EC 50 01 00 00 0F 57
*/
bool Execute(const CString& aCommand, FixedWString& aArgs, const FixedWString& aWorkingDirectory,
const ExecutionFlags aFlags);

/// @pattern 48 89 5C 24 08 57 48 83 EC 20 48 8B D9 41 0F B6 F8 48 8B 89 10 20 00 00 FF 15 ? ? 4B 00 85 C0
bool Terminate(const uint32_t aExitCode, const bool aCloseHandles);

/// @pattern 48 83 EC 48 48 8B 89 10 20 00 00 FF 15 ? ? 4B 00 85 C0 74 4A 3D 02 01 00 00 74 3C FF 15 ? ?
bool WaitUntilCompleted(const uint32_t aTimeoutMS) const;

wchar_t command[0x1000]; // 0000
PHANDLE readPipe; // 2000
PHANDLE writePipe; // 2008
HANDLE handle; // 2010
HANDLE hThread; // 2018
uint64_t unk2; // 2020
DWORD errorCode; // 2028
};

// DEFINE_ENUM_FLAG_OPERATORS(Process::ExecutionFlags);
// DEFINE_ENUM_FLAG_OPERATORS(Process::ReadFlags);
Comment on lines +107 to +108
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If commented, just remove it.

} // namespace RED4ext

#ifdef RED4EXT_HEADER_ONLY
#include <RED4ext/Process-inl.hpp>
#endif