将整数转换为字符串会使注入的父进程崩溃 [Delphi]
Converting Integer to String crashes Injected Parent Process [Delphi]
我的应用程序是一个 x64 Windows 控制台应用程序,需要将自身注入另一个 运行 进程。从命令行执行时,输入要注入的进程的 PID 作为命令行参数。
在父进程下线程 运行 的上下文中,我可以使用字符串变量,但我很难弄清楚如何将整数转换为字符串Delphi。我尝试从 Integer 转换为 String 的所有内容都会导致父进程崩溃。我知道标准 Delphi RTL 命令不会起作用,我需要使用 WINAPI 函数。
这是我尝试过的一些命令的列表:
一个。 IntToStr(int) 使父进程崩溃;
b。 itoa(src, dst, radix) 使父进程崩溃;
c。 strcpy(dst, src) 使父进程崩溃;
我已经包含了一段在 Delphi RAD Studio RIO 10.3.2 中编译的工作代码片段。请务必将目标平台设置为 Windows-64 位。按原样,该程序只是简单地注入一个进程并显示一个 MessageBox。我已经包含并注释掉了使父进程崩溃的命令。
在此示例程序中,我尝试显示使用 GetCurrentProcessId() 确定的 运行 进程的 PID,其中 returns PID 作为整数。挑战在于尝试将变量 'x' 转换为字符串变量 's'。我还尝试使用 itoa() 将 'x' 转换为 PAnsiChar 变量,但失败了。
我预计我的问题可能是我没有加载正确的 Windows 库,或者我没有定义我尝试使用的 WINAPI 函数。
任何帮助将不胜感激,因为我被困住了,在我克服这个障碍之前无法前进。
program Inject;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Variants,
System.Classes,
Winapi.Windows,
Winapi.Messages,
ShellAPI,
System.Win.crtl,
shlobj;
var
ClassName: string;
ProcessHandle: Thandle;
Active : Integer;
PID : integer;
Module, NewModule: Pointer;
Size: SIZE_T;
BytesWritten: SIZE_T;
TID: DWORD;
procedure Main;
var
x : Integer;
s : string;
p : PAnsiChar;
begin
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
LoadLibrary('msvcrt.dll');
LoadLibrary('win32.dll');
x := GetCurrentProcessId;
{ This command crashes the parent process }
// s := IntToStr(x);
{ This command crashes the parent process }
// itoa(x, p, 10);
{ This command crashes the parent process }
strcpy(P, PAnsiChar(IntToStr(x)));
{ A standard Message Box works }
MessageBox(0, 'This Message Box produced by Thread running under Parent Process', 'Process ID', 0);
{ This Message Box crashes the parent process }
// MessageBox(0, PWideChar(IntToStr(x)), 'Process ID', 0);
ExitThread(0);
end;
begin
try
if (ParamCount() > 0) then
begin
PID := StrToInt(ParamStr(1));
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Module := Pointer(GetModuleHandle(nil));
Size := PImageOptionalHeader64(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;
VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE);
NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten);
CreateRemoteThread(ProcessHandle, nil, 0, @Main, Module, 0, TID);
WaitForSingleObject(ProcessHandle, 1000);
end
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
在您的 Main()
过程中,当调用 itoa()
或 strcpy()
时,您的 p
变量是一个 未初始化的指针 ,它不指向任何有效的内存。您需要分配内存来写入,例如:
procedure Main;
var
x : Integer;
str : array[0..12] of AnsiChar;
begin
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
LoadLibrary('msvcrt.dll');
LoadLibrary('win32.dll');
x := GetCurrentProcessId;
itoa(x, str, 10);
MessageBoxA(0, str, 'Process ID', 0);
ExitThread(0);
end;
在 strcpy()
的情况下,您还有一个额外的问题,即 IntToStr()
in Delphi 2009+ returns a UnicodeString
,而不是 AnsiString
,所以你对 PAnsiChar
的类型转换无论如何都是错误的。
或者,查看 user32.dll
中的 Win32 wsprintfA()
函数:
procedure Main;
var
x : Integer;
str : array[0..12] of AnsiChar;
begin
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
LoadLibrary('msvcrt.dll');
LoadLibrary('win32.dll');
x := GetCurrentProcessId;
wsprintfA(str, '%d', x);
MessageBoxA(0, str, 'Process ID', 0);
ExitThread(0);
end;
我的应用程序是一个 x64 Windows 控制台应用程序,需要将自身注入另一个 运行 进程。从命令行执行时,输入要注入的进程的 PID 作为命令行参数。
在父进程下线程 运行 的上下文中,我可以使用字符串变量,但我很难弄清楚如何将整数转换为字符串Delphi。我尝试从 Integer 转换为 String 的所有内容都会导致父进程崩溃。我知道标准 Delphi RTL 命令不会起作用,我需要使用 WINAPI 函数。
这是我尝试过的一些命令的列表:
一个。 IntToStr(int) 使父进程崩溃;
b。 itoa(src, dst, radix) 使父进程崩溃;
c。 strcpy(dst, src) 使父进程崩溃;
我已经包含了一段在 Delphi RAD Studio RIO 10.3.2 中编译的工作代码片段。请务必将目标平台设置为 Windows-64 位。按原样,该程序只是简单地注入一个进程并显示一个 MessageBox。我已经包含并注释掉了使父进程崩溃的命令。
在此示例程序中,我尝试显示使用 GetCurrentProcessId() 确定的 运行 进程的 PID,其中 returns PID 作为整数。挑战在于尝试将变量 'x' 转换为字符串变量 's'。我还尝试使用 itoa() 将 'x' 转换为 PAnsiChar 变量,但失败了。
我预计我的问题可能是我没有加载正确的 Windows 库,或者我没有定义我尝试使用的 WINAPI 函数。
任何帮助将不胜感激,因为我被困住了,在我克服这个障碍之前无法前进。
program Inject;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Variants,
System.Classes,
Winapi.Windows,
Winapi.Messages,
ShellAPI,
System.Win.crtl,
shlobj;
var
ClassName: string;
ProcessHandle: Thandle;
Active : Integer;
PID : integer;
Module, NewModule: Pointer;
Size: SIZE_T;
BytesWritten: SIZE_T;
TID: DWORD;
procedure Main;
var
x : Integer;
s : string;
p : PAnsiChar;
begin
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
LoadLibrary('msvcrt.dll');
LoadLibrary('win32.dll');
x := GetCurrentProcessId;
{ This command crashes the parent process }
// s := IntToStr(x);
{ This command crashes the parent process }
// itoa(x, p, 10);
{ This command crashes the parent process }
strcpy(P, PAnsiChar(IntToStr(x)));
{ A standard Message Box works }
MessageBox(0, 'This Message Box produced by Thread running under Parent Process', 'Process ID', 0);
{ This Message Box crashes the parent process }
// MessageBox(0, PWideChar(IntToStr(x)), 'Process ID', 0);
ExitThread(0);
end;
begin
try
if (ParamCount() > 0) then
begin
PID := StrToInt(ParamStr(1));
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Module := Pointer(GetModuleHandle(nil));
Size := PImageOptionalHeader64(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;
VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE);
NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten);
CreateRemoteThread(ProcessHandle, nil, 0, @Main, Module, 0, TID);
WaitForSingleObject(ProcessHandle, 1000);
end
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
在您的 Main()
过程中,当调用 itoa()
或 strcpy()
时,您的 p
变量是一个 未初始化的指针 ,它不指向任何有效的内存。您需要分配内存来写入,例如:
procedure Main;
var
x : Integer;
str : array[0..12] of AnsiChar;
begin
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
LoadLibrary('msvcrt.dll');
LoadLibrary('win32.dll');
x := GetCurrentProcessId;
itoa(x, str, 10);
MessageBoxA(0, str, 'Process ID', 0);
ExitThread(0);
end;
在 strcpy()
的情况下,您还有一个额外的问题,即 IntToStr()
in Delphi 2009+ returns a UnicodeString
,而不是 AnsiString
,所以你对 PAnsiChar
的类型转换无论如何都是错误的。
或者,查看 user32.dll
中的 Win32 wsprintfA()
函数:
procedure Main;
var
x : Integer;
str : array[0..12] of AnsiChar;
begin
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
LoadLibrary('msvcrt.dll');
LoadLibrary('win32.dll');
x := GetCurrentProcessId;
wsprintfA(str, '%d', x);
MessageBoxA(0, str, 'Process ID', 0);
ExitThread(0);
end;