How to extract Unicode character sequences from an MZ executable?

I want to get Unicode strings from binary (".exe") files.

When I use this code:

    'unicode_str = re.compile( u'[\u0020-\u007e]{1,}',re.UNICODE )'

this works, but only returns split characters, so when I try to change the quantifier to 3:

Python:       unicode_str = re.compile( u'[\u0020-\u007e]{3,}',re.UNICODE )

Perl:       my @a = ( $file =~ /[\x{0020}-\x{007e}]{3,}/gs );

I get only ASCII characters, all Unicode characters have disappeared.

Where did I make a mistake or maybe I don't know anything about Unicode?


Code from comments:

Python:

File = open( sys.argv[1], "rb" )
FileData = File.read()
File.close()
unicode_str = re.compile( u'[\u0020-\u007e]{3,}',re.UNICODE )
myList = unicode_str.findall(FileData)
for p in myList:
    print p

Perl:

$/ = "newline separator";
my $input = shift;
open( File, $input );
my $file = <File>;
close( File );
my @a = ( $file =~ /[\x{0020}-\x{007e}]{3,}/gs );
foreach ( @a ) { print "$_\n"; }
+3
source share
2 answers

Someone already wrote a utility that does what you want:

http://technet.microsoft.com/en-us/sysinternals/bb897439.aspx

usage: strings [-a] [-f offset] [-b bytes] [-n length] [-o] [-q] [-s] [-u] <file or directory>

Strings takes wild-card expressions for file names, and additional command line parameters are defined as follows:

-a  Ascii-only search (Unicode and Ascii is default)
-b  Bytes of file to scan
-f  File offset at which to start scanning.
-o  Print offset in file string was located
-n  Minimum string length (default is 3)
-q  Quiet (no banner)
-s  Recurse subdirectories
-u  Unicode-only search (Unicode and Ascii is default)  

To search one or more files for the presence of a particular string using strings use a command like this:

strings * | findstr /i TextToSearchFor

Edit:

, Python, , Unicode , UTF-16LE. Unicode. , strings

import re
data = open('c:/users/metolone/util/windiff.exe','rb').read()

# Search for printable ASCII characters encoded as UTF-16LE.
pat = re.compile(ur'(?:[\x20-\x7E][\x00]){3,}')
words = [w.decode('utf-16le') for w in pat.findall(data)]
for w in words:
    print w
+3
use Win32::Exe;
my $exe = Win32::Exe->new('foo.exe');
my $inforef = $exe->get_version_info;
printf "%s: %s\n", $_, $inforef->{$_} for qw(Comments CompanyName
    FileDescription FileVersion InternalName LegalCopyright
    LegalTrademarks OriginalFilename ProductName ProductVersion);

UTF16-BE, Encode:

use Encode qw(decode encode);
my $octets = # extracted from the exe
    "\x00\x73\x00\x6f\x00\x66\x00\x74\x00\x20\x00\x43\x00\x6f" .
    "\x00\x70\x00\x6f\x00\x72\x00\x61\x00\x74\x00\x69\x00\x6f";
my $characters = decode 'UTF16-BE', $octets, Encode::FB_CROAK;
# 'soft Coporatio'
0

All Articles