2013-11-28 41 views
0

我想编写一个程序来读取/提取.exe文件中的所有有效字符串(例如:“该程序必须在Win下运行”或“MZ”),与sysinternalsStrings.exe完全相同。 其实我想扫描.exe文件,如果它包含特殊的字符串值,如"ekrn.exe""Filrefox.exe"然后检测到该文件为可疑文件(杀死ekrn.exe或注入malcode firefox.exe)。从德尔福的.exe文件(如Strings.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ب@[email protected]¤"@[email protected]@@[email protected]@[email protected] Charے[email protected]ے€@Byteک@Wordے°@Pointerؤ@Cardinalےےےà@ NativeIntےےےü@ 
NativeUIntے@ShortStringے,@ [email protected]@[email protected]Œ@[email protected]ے€@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

任何想法的字符串的结果? 我该怎么办?

+1

你不这样做['字符串(1)'](HTTP:// www.freebsd.org/cgi/man.cgi?query=strings&sektion=1)。请考虑阅读整个说明。 –

+1

['ASCII range'](http://www.asciitable.com/)中的一些字符是不可显示的。 1)从第一个可显示的字符中扫描缓冲区,直到达到无法显示的字符(或者,您不想显示的字符)。这是你可以存储在某个地方的一个词。 2)转到步骤1 – TLama

+1

要特别注意第一条评论中提到的链接中的“可打印字符”。你为什么偶尔给lSearch分配0? –

回答

1

AsciiDump通过编码{} [email protected]

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; 
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; 
+0

http://www.cplusplus.com/reference/cctype/isprint/ –

+0

@FreeConsulting:这是一个C/C++函数,它在Delphi中不可用。 –

+0

谢谢你指点我!我从来不知道这一点。 –