从Delphi中的.exe文件(如Strings.exe)中读取字符串

时间:2013-11-28 00:42:39

标签: string delphi exe

我想编写一个程序来读取/提取.exe文件中的所有有效字符串(例如:“此程序必须在Win下运行”或“MZ”),正如Strings.exesysinternals。 实际上我想扫描一个.exe文件,如果它包含特殊字符串值,例如"ekrn.exe""Filrefox.exe",则将该文件检测为可疑文件(Killing ekrn.exe或者注入malcode到firefox.exe)。

我在Delphi中编写了以下代码:

const
  TargetName = 'E:\AntiDebugg.exe';
var
  hFile: THandle;
  tmp: AnsiString;
  dwFileSize, lChar, lSearch: Integer;
  dwNumRead: Cardinal;
  dwBuffer: array of AnsiChar;
begin
  mmo1.Clear;

  hFile := CreateFileA(TargetName, GENERIC_READ, FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

  dwFileSize := GetFileSize(hFile, nil);
  SetLength(dwBuffer, dwFileSize);

  lChar := 0;
  lSearch := 0;

  while lChar <= dwFileSize do
  begin
    ReadFile(hFile, dwBuffer[lChar], SizeOf(dwBuffer), dwNumRead, nil);
    while dwBuffer[lChar] <> '' do
    begin
      tmp := tmp + dwBuffer[lChar];
      Inc(lChar, 1);
    end;
    lSearch := 0;
    Inc(lChar, 1);
  end;
  mmo1.Text := (tmp);
  CloseHandle(hFile);

运行我的代码的结果是(一小块):

MZPےے¸@؛´   ح!¸Lح!گگThis program must be run under Win32
$7PEL
%0فQà´أ\
¤"0Bگب.textd­ .itext| .data`@.bssطN.idata\
@.didataب@.tls.rdata@.reloc¤"@.rsrc@@@Boolean@alseTrueSystem4@AnsiCharP@    Charےh@Integerے€@Byteک@Wordے°@Pointerؤ@Cardinalےےےà@    NativeIntےےےü@
NativeUIntے@ShortStringے,@  PAnsiChar0@D@stringT@TClassŒ@h@HRESULTے€@TGUID

但这不是我想要的结果,我期望的结果是:

MZP
This program must be run under Win32
.text
`.itext
`.data
.bss
.idata
.didata
.tls
.rdata
@.reloc
B.rsrc
Boolean
False
True
System
AnsiChar
Char
Integer
Byte
Word
Pointer
Cardinal
NativeInt
NativeUInt
ShortString
PAnsiChar0
string
TClass
HRESULT
TGUID
  • 在此示例中,由Delphi编译的AntiDebugg.exe

Strings.exe对“AntiDebugg.exe”

字符串的结果

enter image description here

有什么想法吗? 我该怎么办?

2 个答案:

答案 0 :(得分:4)

尝试这样的事情:

const
  TargetName = 'E:\AntiDebugg.exe';
  MinStringLength = 2;

var
  hFile: THandle;
  hMapping: THandle;
  pView: Pointer;  
  dwFileSize: DWORD;
  pCurrent, pEOF, pStart: PAnsiChar;
  iLen: Integer;
begin
  mmo1.Clear;

  hFile := CreateFile(TargetName, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if hFile = INVALID_HANDLE_VALUE then RaiseLastOSError;
  try
    dwFileSize := GetFileSize(hFile, nil);
    if dwFileSize = $FFFFFFFF then RaiseLastOSError;

    hMapping := CreateFileMapping(hFile, nil, PAGE_READONLY, 0, dwFileSize, nil);
    if hMapping = 0 then RaiseLastOSError;
    try
      pView := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, dwFileSize);
      if pView = nil then RaiseLastOSError;
      try
        pCurrent := PAnsiChar(pView);
        pEOF := pCurrent + dwFileSize;
        pStart := nil;

        while pCurrent < pEOF do
        begin
          if pCurrent^ in [#9, #10, #13, #32..#128] then
          begin
            if pStart = nil then
              pStart := pCurrent;
          end
          else if pStart <> nil then
          begin
            iLen := Integer(pCurrent - pStart);
            if iLen >= MinStringLength then
            begin
              SetString(tmp, pStart, iLen);
              mmo1.Lines.Add(tmp);
            end;
            pStart := nil;
          end;
          Inc(pCurrent);
        end;
      finally
        UnmapViewOfFile(pView);
      end;
    finally
     CloseHandle(hMapping);
    end;
  finally
    CloseHandle(hFile);
  end;
end;

答案 1 :(得分:1)

由{steve10120@ic0de.org}编码的AsciiDump

function FileToPtr(szFilePath: string; var pFile: Pointer;

  var dwFileSize: DWORD): Boolean;

var

  hFile: DWORD;

  dwRead: DWORD;

begin

  Result := FALSE;

  hFile := CreateFile(PChar(szFilePath), GENERIC_READ, 0, nil,

    OPEN_EXISTING, 0, 0);

  if (hFile <> INVALID_HANDLE_VALUE) then

  begin

    dwFileSize := GetFileSize(hFile, nil);

    if (dwFileSize > 0) then                                  

    begin

      pFile := VirtualAlloc(nil, dwFileSize, MEM_COMMIT, PAGE_READWRITE);

      if (Assigned(pFile)) then

      begin

        SetFilePointer(hFile, 0, nil, FILE_BEGIN);

        ReadFile(hFile, pFile^, dwFileSize, dwRead, nil);

        if (dwRead = dwFileSize) then

          Result := TRUE;

      end;

    end;

    CloseHandle(hFile);

  end;

end;



function FindASCIIStringsA(szFilePath: string; dwMinLength: DWORD;

  szDumpPath: string): Boolean;

var

  pFile: Pointer;

  dwFileSize: DWORD;

  i: DWORD;

  szDump: string;

  dwLength: DWORD;

  hFile: TextFile;

begin

  Result := FALSE;

  if (FileToPtr(szFilePath, pFile, dwFileSize)) then

  begin

    dwLength := 0;

    AssignFile(hFile, szDumpPath);

    // yeah I don't like it but its easiest for writing lines..

    Rewrite(hFile);

    for i := 0 to (dwFileSize - 1) do

    begin

      if (PByte(DWORD(pFile) + i)^ in [$20 .. $7E]) then

      begin

        szDump := szDump + Char(PByte(DWORD(pFile) + i)^);

//        WriteLn(hFile, '0x' + IntToHex(i - dwLength, 8) + ': ' + szDump);

        Inc(dwLength);

      end

      else

      begin

        if (dwLength >= dwMinLength) then

          WriteLn(hFile, '0x' + IntToHex(i - dwLength, 8) + ': ' + szDump);

        dwLength := 0;

        szDump := '';

      end;

    end;

    if (FileSize(hFile) > 0) then

      Result := TRUE;

    CloseFile(hFile);

    VirtualFree(pFile, 0, MEM_RELEASE);

  end;

end;

function FindASCIIStrings(szFilePath:string; dwMinLength:DWORD; szDumpPath:string):Boolean;

var

  pFile:      Pointer;

  dwFileSize: DWORD;

  IDH:        PImageDosHeader;

  INH:        PImageNtHeaders;

  i:          DWORD;

  szDump:     string;

  dwLength:   DWORD;

  hFile:      TextFile;

begin

  Result := FALSE;

  if (FileToPtr(szFilePath, pFile, dwFileSize)) then

  begin

    IDH := pFile;

    if (IDH^.e_magic = IMAGE_DOS_SIGNATURE) then

    begin

      INH := Pointer(DWORD(pFile) + IDH^._lfanew);

      if (INH^.Signature = IMAGE_NT_SIGNATURE) then

      begin

        dwLength := 0;

        AssignFile(hFile, szDumpPath); // yeah I don't like it but its easiest for writing lines..

        Rewrite(hFile);

        for i := INH^.OptionalHeader.SizeOfHeaders to (dwFileSize - 1) do

        begin

          if (PByte(DWORD(pFile) + i)^ in [$20..$7E]) then

          begin

            szDump := szDump + Char(PByte(DWORD(pFile) + i)^);

            Inc(dwLength);

          end

          else

          begin

            if (dwLength >= dwMinLength) then

              WriteLn(hFile, '0x' + IntToHex(i - dwLength, 8) + ': ' + szDump);

            dwLength := 0;

            szDump := '';

          end;

        end;

        if (FileSize(hFile) > 0) then

          Result := TRUE;

        CloseFile(hFile);

      end;

    end;

    VirtualFree(pFile, 0, MEM_RELEASE);

  end;

end;

procedure TForm2.btn1Click(Sender: TObject);

begin

FindASCIIStrings('e:\AntiDebugg.exe', 2,

    IncludeTrailingPathDelimiter(ExtractFilePath(param  str(0))) +

    ExtractFileName(paramstr(1)) + '.dmp')

end;