String Viewer 0.02 by dila
--------------------------------------------------------------------------------
ASCII strings are found by scanning for NULL bytes in the PE. The algo then checks every character in the string to see if it isalnum(). you could replace this function and extend the number of 'string' chars, but this will make false positives more common.
please post your fixes/comments!
Code:
/*
String Viewer PEiD Plugin v0.02
Minor update on 13.02.05
http://dila.mine.nu
*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <commctrl.h>
#include <commdlg.h>
#include "defs.h"
#include "resource.h"
BOOL CALLBACK DlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
void DialogSetup( HWND hDlg );
void SetClipboardText( HWND hDlg );
int SavePEStrings( HWND hDlg );
int WriteStringsFile( HWND hDlg, HANDLE hFile, char *cFileData, int iItemCount );
int LoadPEFile( HWND hDlg );
int FindStrings( HWND hDlg, HANDLE hFile, DWORD dwSize, char *cFileData );
void AddString( HWND hDlg, char *cOffset, char *cString );
// Structs mostly for listview control
HMENU hMenu;
POINT lpCursPos;
OPENFILENAMEA lpSfn;
LVCOLUMN lvColumn;
LVITEM lvItem;
NMHDR *nMsg;
// Minimum length of strings to find
unsigned int iMinLength = 5;
HINSTANCE hgInstance;
char *cFileName, cOutputName[304];
char cDFilter[] = "Text Files (*.txt)\0*.txt";
char cDTitle[] = "Select path for file...";
char cError[][126] = {
"ERROR: Could not locate file!",
"ERROR: File has zero length!",
"ERROR: Memory allocation failed!",
"ERROR: Could not read from file!"
};
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
// Store module handle
hgInstance = hinstDLL;
// Load right-click menu
hMenu = LoadMenu( hgInstance, MAKEINTRESOURCE(IDMENU) );
hMenu = GetSubMenu( hMenu, 0 );
return true;
}
DWORD DoMyJob( HWND hMainDlg, char *szFname, DWORD lpReserved, LPVOID lpParam )
{
// Get name of file loaded in PEiD
cFileName = (char *)szFname;
// Create the window
DialogBoxParam( hgInstance, MAKEINTRESOURCE(IDDLG), hMainDlg, (DLGPROC)DlgProc, 0 );
// Unlock and restore PEiD window
EnableWindow( hMainDlg, 1 );
SetFocus( hMainDlg );
return 1;
}
LPSTR LoadDll()
{
// Set the plugin name in PEiD
return "String viewer";
}
BOOL CALLBACK DlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg )
{
case WM_INITDIALOG:
// Main function
DialogSetup( hDlg );
return true;
case WM_COMMAND:
if ( wParam == IDCOPY )
{ // Handle 'copy' menu click
SetClipboardText( hDlg );
} else if ( wParam == IDDUMP )
{ // Handle 'dump' menu click
if ( !GetSaveFileName( &lpSfn ) ) break;
int iResult = SavePEStrings( hDlg );
if ( iResult != 0 && iResult != 4 )
MessageBox( hDlg, cError[iResult-1], "Dump error", MB_OK|MB_ICONSTOP );
}
return true;
case WM_NOTIFY:
nMsg = (NMHDR *)lParam;
if ( nMsg->code == NM_RCLICK )
{ // Handle listview right-click event
GetCursorPos( &lpCursPos );
TrackPopupMenuEx( hMenu, 0, lpCursPos.x, lpCursPos.y, hDlg, 0 );
}
return true;
case WM_CLOSE:
// Close the window
DestroyWindow( hDlg );
return true;
}
return false;
}
void DialogSetup( HWND hDlg )
{
char cLCol1[] = "Address";
char cLCol2[] = "String";
// Initialize our structures
memset( &lpSfn, 0, sizeof(OPENFILENAMEA) );
memset( &lvColumn, 0, sizeof(LVCOLUMN) );
memset( &lvItem, 0, sizeof(LVITEM) );
// Setup 'dump' common dialog
sprintf( cOutputName, "%s.txt", cFileName );
lpSfn.lStructSize = sizeof(OPENFILENAMEA);
lpSfn.hwndOwner = hDlg;
lpSfn.Flags = OFN_PATHMUSTEXIST|OFN_LONGNAMES|OFN_EXPLORER|OFN_HIDEREADONLY ;
lpSfn.lpstrFilter = cDFilter;
lpSfn.nFilterIndex = 1;
lpSfn.lpstrTitle = cDTitle;
lpSfn.lpstrFile = cOutputName;
lpSfn.nMaxFile = sizeof(cOutputName);
// Setup first column in listview
lvColumn.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
lvColumn.iSubItem = 0;
lvColumn.cx = 62;
lvColumn.cchTextMax = sizeof(cLCol1) - 1;
lvColumn.pszText = (LPSTR)&cLCol1;
SendDlgItemMessage( hDlg, IDLIST, LVM_INSERTCOLUMN, 0, (LPARAM)(LPLVCOLUMN)&lvColumn );
// Setup second column in listview
lvColumn.iSubItem = 1;
lvColumn.cx = 366;
lvColumn.cchTextMax = sizeof(cLCol2) - 1;
lvColumn.pszText = (LPSTR)&cLCol2;
SendDlgItemMessage( hDlg, IDLIST, LVM_INSERTCOLUMN, 1, (LPARAM)(LPLVCOLUMN)&lvColumn );
// Setup item struct for listview
lvItem.mask = LVIF_TEXT|LVCF_SUBITEM;
// Populate the listview control
SendDlgItemMessage( hDlg, IDLIST, LVM_DELETEALLITEMS, 0, 0 );
int iResult = LoadPEFile( hDlg );
if ( iResult != 0 ) AddString( hDlg, 0, cError[iResult-1] );
return;
}
void SetClipboardText( HWND hDlg )
{
// Get the selected item and check it is valid
int iSelected = (int)SendDlgItemMessage( hDlg, IDLIST, LVM_GETNEXTITEM, -1, LVNI_SELECTED );
if ( iSelected == -1 ) return;
// Get the item offset
char cAddress[9];
lvItem.iSubItem = 0;
lvItem.cchTextMax = 9;
lvItem.pszText = (LPSTR)&cAddress;
SendDlgItemMessage( hDlg, IDLIST, LVM_GETITEMTEXT, iSelected, (LPARAM)&lvItem );
// Get the item string
char cString[256];
lvItem.iSubItem = 1;
lvItem.cchTextMax = 256;
lvItem.pszText = (LPSTR)&cString;
int iStringLength = (int)SendDlgItemMessage( hDlg, IDLIST, LVM_GETITEMTEXT, iSelected, (LPARAM)(LPLVITEM)&lvItem );
// Allocate memory and prepare the string
HGLOBAL hgcString = GlobalAlloc( GMEM_MOVEABLE, iStringLength+12 );
char *cCopyBuffer = (char *)GlobalLock( hgcString );
memset( cCopyBuffer, 0, sizeof(cCopyBuffer) );
sprintf( cCopyBuffer, "%s: %s", cAddress, cString );
// Prepare clipboard and set text
OpenClipboard( hDlg );
EmptyClipboard();
SetClipboardData( CF_TEXT, (char *)cCopyBuffer );
// Close clipboard and clean up
GlobalUnlock( cCopyBuffer );
CloseClipboard();
memset( &lvItem, 0, sizeof(LVITEM) );
lvItem.mask = LVIF_TEXT|LVCF_SUBITEM;
return;
}
int SavePEStrings( HWND hDlg )
{
// Count items in listview
int iCount = (int)SendDlgItemMessage( hDlg, IDLIST, LVM_GETITEMCOUNT, 0, 0 );
if ( iCount == 0 ) return 1;
// Open output file for writing
HANDLE hFile = CreateFile( cOutputName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0 );
if ( !hFile ) return 2;
// Allocate memory for file, make sure it worked
char *cFileData = (char *)malloc( iCount*266 );
if ( !cFileData ) return 3;
// Construct the data and write file
int iResult = WriteStringsFile( hDlg, hFile, cFileData, iCount );
// Close file and deallocate memory
CloseHandle( hFile );
free( cFileData );
return iResult;
}
int WriteStringsFile( HWND hDlg, HANDLE hFile, char *cFileData, int iItemCount )
{
// Prepare buffers
char *cpFileData = cFileData;
char cAddress[9]; char cString[256];
int iStringLength = 0; int iFileLength = 0;
int iCount = 0;
memset( cFileData, 0, sizeof(cFileData) );
// Construct the string list
for ( ; iCount <= iItemCount; ++iCount )
{
lvItem.iSubItem = 0;
lvItem.cchTextMax = 9;
lvItem.pszText = (LPSTR)&cAddress;
SendDlgItemMessage( hDlg, IDLIST, LVM_GETITEMTEXT, iCount, (LPARAM)&lvItem );
lvItem.iSubItem = 1;
lvItem.cchTextMax = 256;
lvItem.pszText = (LPSTR)&cString;
iStringLength = (int)SendDlgItemMessage( hDlg, IDLIST, LVM_GETITEMTEXT, iCount, (LPARAM)(LPLVITEM)&lvItem );
sprintf( cpFileData, "%s: %s\r\n", cAddress, cString );
cpFileData += strlen(cString)+12;
iFileLength += (int)strlen(cString)+12;
}
// Write memory to file, return any errors
DWORD dwBytesWriten;
int iResult = WriteFile( hFile, cFileData, iFileLength-2, &dwBytesWriten, 0 );
if ( !iResult ) return 4;
return 0;
}
int LoadPEFile( HWND hDlg )
{
// Open input file for reading
HANDLE hFile = CreateFile( cFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0 );
if ( !hFile ) return 1;
// Get file size in bytes, make sure its not zero
DWORD dwSize = GetFileSize( hFile, 0 );
if ( dwSize == 0xFFFFFFFF ) return 2;
// Allocate memory for file, make sure it worked
char *cFileData = (char *)malloc( dwSize );
if ( !cFileData ) return 3;
// Begin ASCII hunt
int iResult = FindStrings( hDlg, hFile, dwSize, cFileData );
// Deallocate memory and return any errors
free( cFileData );
return iResult;
}
int FindStrings( HWND hDlg, HANDLE hFile, DWORD dwSize, char *cFileData )
{
// Read file contents into the allocated memory
DWORD dwBytesRead;
BOOL iResult = ReadFile( hFile, cFileData, dwSize, &dwBytesRead, 0 );
if ( !iResult ) return 4;
// Tell system we finished reading
CloseHandle( hFile );
// ...And here is the algo
long int iFileByte = dwSize;
char cAddress[9];
char *cpFileByte;
for ( ; iFileByte > 0; --iFileByte )
{ // Loop for each byte in the file
if ( cFileData[iFileByte] == '\0' && isalnum(cFileData[iFileByte-1]) )
{ // If a string was found...
cpFileByte = cFileData + iFileByte - 1;
while ( isalnum(cpFileByte[0]) || cpFileByte[0] == ' ' )
{
if ( cpFileByte[-1] == '\0' && isalnum(cpFileByte[-2]) ) cpFileByte[-1] = ' ';
cpFileByte -= 1;
}
++cpFileByte;
if ( isalnum(cpFileByte[0]) || cpFileByte[0] == ' ' ) ++cpFileByte;
if ( strlen(cpFileByte) >= iMinLength )
{
--cpFileByte;
sprintf( cAddress, "%08X", iFileByte );
AddString( hDlg, cAddress, cpFileByte );
}
iFileByte -= (int)strlen(cpFileByte);
}
}
return 0;
}
void AddString( HWND hDlg, char *cOffset, char *cString )
{
// Fill struct for address column and add it
lvItem.cchTextMax = sizeof(cOffset) - 1;
lvItem.pszText = (LPSTR)cOffset;
lvItem.iSubItem = 0;
SendDlgItemMessage( hDlg, IDLIST, LVM_INSERTITEM, 0, (LPARAM)(LPLVITEM)&lvItem );
// Fill struct for string column and add it
lvItem.cchTextMax = sizeof(cString) - 1;
lvItem.pszText = (LPSTR)cString;
lvItem.iSubItem = 1;
SendDlgItemMessage( hDlg, IDLIST, LVM_SETITEM, 0, (LPARAM)(LPLVITEM)&lvItem );
return;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)