Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Delphi从记事本读取进程内存_String_Delphi_Notepad_Readprocessmemory - Fatal编程技术网

String Delphi从记事本读取进程内存

String Delphi从记事本读取进程内存,string,delphi,notepad,readprocessmemory,String,Delphi,Notepad,Readprocessmemory,我想提取记事本进程的完整进程内存,并将其写入文本文件。 问题是在文本文件中找不到我在记事本中键入的内容。 例如,如果在记事本中键入“test123”,则在程序创建的文本文件中找不到字符串。 代码如下: {$APPTYPE CONSOLE} uses Windows, TLHelp32, SysUtils; var Snap, err: dword; sysinfo: TSystemInfo; Process: TPROCESSENTRY32; Handle: TH

我想提取记事本进程的完整进程内存,并将其写入文本文件。 问题是在文本文件中找不到我在记事本中键入的内容。 例如,如果在记事本中键入“test123”,则在程序创建的文本文件中找不到字符串。 代码如下:

{$APPTYPE CONSOLE}

uses
  Windows,
  TLHelp32,
  SysUtils;

var
  Snap, err: dword;
  sysinfo: TSystemInfo;
  Process: TPROCESSENTRY32;
  Handle: THandle;
  Mbi: TMemoryBasicInformation;
  Addr, BytesRead: dword;
  Buf: PChar;
  f: TextFile;
begin
  GetSystemInfo(sysinfo);
        Handle := OpenProcess(PROCESS_ALL_ACCESS, false, 2928);
        if Handle <> 0 then
        begin
          writeln(Process.szExeFile);
          Addr := dword(sysinfo.lpMinimumApplicationAddress);
          while (Addr < $80000000) do
          begin
            if VirtualQueryEx(Handle, Ptr(Addr), Mbi, SizeOf(Mbi)) = 0 then
            begin
              err := GetLastError;
              inc(Addr, sysinfo.dwPageSize);
              continue;
            end;
             Buf := AllocMem(Mbi.RegionSize);
             ReadProcessMemory(Handle, Mbi.BaseAddress, Buf, Mbi.RegionSize, BytesRead);
             AssignFile(f, 'Test.txt');
             Append(f);
             WriteLn(f, Buf);
             CloseFile(f);
             FreeMem(Buf);
            if Addr + Mbi.RegionSize < Addr then
              break;
            Addr := Addr + Mbi.RegionSize;
          end;
          CloseHandle(Handle)
        end;
  Readln;
end.
{$APPTYPE控制台}
使用
窗户,
TL32,
SysUtils;
变量
Snap,err:dword;
sysinfo:TSystemInfo;
进程:tprocesentry32;
手柄:坦德尔;
Mbi:TMemoryBasicInformation;
地址,字节:dword;
Buf:PChar;
f:文本文件;
开始
GetSystemInfo(sysinfo);
Handle:=OpenProcess(PROCESS\u ALL\u ACCESS,false,2928);
如果句柄为0,则
开始
writeln(Process.szExeFile);
地址:=dword(sysinfo.lpminimumApplication地址);
而(地址<80000000美元)则
开始
如果VirtualQueryEx(句柄、Ptr(Addr)、Mbi、SizeOf(Mbi))=0,则
开始
err:=GetLastError;
inc(地址,sysinfo.dwPageSize);
继续;
结束;
Buf:=AllocMem(Mbi.RegionSize);
ReadProcessMemory(句柄,Mbi.BaseAddress,Buf,Mbi.RegionSize,字节读取);
赋值文件(f,'Test.txt');
附加(f);
书面(f,Buf);
关闭文件(f);
FreeMem(Buf);
如果Addr+Mbi.RegionSize
记事本可能存储在Windows本机UTF-16中编码的文本。因此,请将该文本视为宽字符串

我想另一个问题是,您正在将二进制数据写入文本文件。内存块中的任何空字符都将终止输出。您真的想停止使用Pascal I/O,只需将此内存转储到文件流。或者,如果您必须使用Pascal I/O,至少可以在二进制模式下对其进行访问


使用自动化API或发送WM_GETTEXT不是更容易吗?

检索记事本文本内容的正确方法是使用
FindWindowEx()
EnumChildWindows()
或类似方法定位记事本编辑字段的
HWND
,然后向其发送
WM_GETTEXT
消息

但若您必须转储记事本分配的内存,那个么您需要修复代码。它会忽略错误,并且不会将检索到的数据正确写入文件。请尝试类似以下内容:

uses
  Windows,
  TLHelp32,
  SysUtils;

var
  err: DWORD;
  sysinfo: TSystemInfo;
  Handle: THandle;
  Mbi: TMemoryBasicInformation;
  Addr: DWORD_PTR;
  BytesRead: DWORD;
  Buf: array of Byte;
  f: TFileStream;
begin
  GetSystemInfo(sysinfo);
  Handle := OpenProcess(PROCESS_ALL_ACCESS, FALSE, 2928);
  if Handle = 0 then
  begin
    err := GetLastError;
    // do something...
  end else
  try
    f := TFileStream.Create('Test.txt', fmCreate);
    try
      Addr := DWORD_PTR(SysInfo.lpMinimumApplicationAddress);
      while (Addr < $80000000) do
      begin
        if VirtualQueryEx(Handle, Pointer(Addr), Mbi, SizeOf(Mbi)) = 0 then
        begin
          err := GetLastError;
          Inc(Addr, sysinfo.dwPageSize);
          Continue;
        end;
        if Mbi.RegionSize > Length(Buf) then
          SetLength(Buf, Mbi.RegionSize);
        if not ReadProcessMemory(Handle, Mbi.BaseAddress, @Buf[0], Mbi.RegionSize, BytesRead) then
        begin
            err := GetLastError;
            // do something...
        end else
          f.WriteBuffer(Buf[0], BytesRead);
        if Addr + Mbi.RegionSize < Addr then
          break;
        Addr := Addr + Mbi.RegionSize;
      end;
    finally
      f.Free;
    end;
  finally
    CloseHandle(Handle);
  end;
  Readln;
end.
使用
窗户,
TL32,
SysUtils;
变量
德沃德;
sysinfo:TSystemInfo;
手柄:坦德尔;
Mbi:TMemoryBasicInformation;
地址:德沃德•普特;
拜特斯拉德:德沃德;
Buf:字节数组;
f:TFileStream;
开始
GetSystemInfo(sysinfo);
Handle:=OpenProcess(PROCESS\u ALL\u ACCESS,FALSE,2928);
如果Handle=0,则
开始
err:=GetLastError;
//做点什么。。。
结束其他
尝试
f:=TFileStream.Create('Test.txt',fmCreate);
尝试
地址:=DWORD_PTR(SysInfo.lpMinimumApplicationAddress);
而(地址<80000000美元)则
开始
如果VirtualQueryEx(句柄、指针(Addr)、Mbi、SizeOf(Mbi))=0,则
开始
err:=GetLastError;
Inc(地址,sysinfo.dwPageSize);
继续;
结束;
如果Mbi.RegionSize>长度(Buf),则
SetLength(Buf,Mbi.RegionSize);
如果不是ReadProcessMemory(句柄,Mbi.BaseAddress,@Buf[0],Mbi.RegionSize,BytesRead),则
开始
err:=GetLastError;
//做点什么。。。
结束其他
f、 WriteBuffer(Buf[0],字节读取);
如果Addr+Mbi.RegionSize
首先,您将无法使用文本文件来编写这样的内存内容;这不是文本。你到底想完成什么?(为什么要读取进程内存以获取文本?)我想从进程内存中提取一些电子邮件地址。我该怎么做?有没有办法将输出转换成文本?你在写恶意软件?我有一个电子邮件提取器,我没有导出电子邮件的串行密钥。不要挣扎,您可以将目标进程转储到文件并分析其内存布局。读取内存后是否应该使用WM_GETTEXT?否。对于记事本,您可以单独使用WM_GETTEXT进行读取。记事本仅用于测试。我可以将WM_GETTEXT用于readprocessmemory输出吗?当然不能。你把它送到窗口。您的问题表明您对记事本感兴趣。是否有方法将readprocessmemory输出转换为文本?正确的方法实际上是使用自动化API。