hi,

i would like to program a tool, that can set passwords dialog on different exes, so that the user first has to type in the correct password to run it. now my question: how to do that? i heard something about PE-file-format, which seems to be the win-exe-format. a little code snippet or something like that wouldn't be bad....

thanks.

nop
Posted on 2001-12-12 14:36:28 by NOP-erator
ahh the refined and lovely art of code appending :)
I've toyed with this a lot sometime ago..and believe me, is this fun or what!!? :)
Yes you'll have to study the P(ortable) E(xecutable) format. why? well because you'll take a compiled closed binary image and you'll modify it and that is not as simple as createfile,writefile,closefile.
You will increase section's size's or even add a section to the exe. And those changes will have to be reflected in the PE header.
Basically you'll have to take an exe file, add the 'dialog box' code, modify the PE header accordingly,change the executable's entrypoint , modify Import Address Table, etc.
It's not very hard, but you'll have to study and code :)
I coded a tool that parses the PE header of a given executable file ('pelabs' is it's name). Get it at www.latigo.cjb.net ('coding' section). Also check some PE tutes i wrote for further info.
There is a tool which exactly does what you want to do and it includes source code, so i guess that the whole thing makes a nice package ;). Get that tool at protools.cjb.net or playtools.cjb.net or at your local tool repository :)

Ask further if you got any doubts..
See you!

Latigo
Posted on 2001-12-12 15:21:39 by latigo
if you understand the pe-header (which would be
a very hard task) it is very very simple to do that...
coz i'm at work right now i canot do this now but
wait till tomorrow and i'll give you the code to append
working code to a executable (maybe a simple msgbox
at start)... until then try to study the pe-header or
my bad-written example in hutchs masm7 sp
(exmpl 8/mob/no_imports)... :(
Posted on 2001-12-13 05:38:00 by mob
here's some code i had to do once. Some guy hired me to make some kind of 'packer'. This is not a packer since it does not compress. It's just a crypter. Takes an exe, crypts it's code section and adds code so the exe will first look for a certain dll to decrypt itself . Easy protection to be bypassed. But that's what they wanted :).
Anyway, here's the code. I never 'released' it so it's not very tidy and there are no readmes and the comments are in spanish. But you are smart enough ;)
Hope it helps.

Latigo
Posted on 2001-12-13 07:57:39 by latigo
here are the dlls used for the encryption and decryption. If these are not present 'LatPack' is useless.


Latigo
Posted on 2001-12-13 08:10:21 by latigo
you can also check my website (http://www.effervescence.com), there is some tuts on reversing
Posted on 2001-12-13 12:30:44 by roy
There is already a EXE password maker :-) (PE)
i also wrote a nive BruteForcer to it :-))
it called "SMT's password protected exe" u can find it in:
Protools.cjb.net / protools.com :alright:
cya all later :-)
Posted on 2001-12-13 13:43:23 by Bengaly
ok, thanks. i'll have a look at it in the weekend, writing a physics test tomorrow.
Posted on 2001-12-13 14:08:26 by NOP-erator
this is ~EXACTLY~ what you want, should be easy
to understand if you're familiar with the pe-header...
at start it let's you choose some executable and
changes this file, the result: on every start a little
msgbox is displayed... bye



.486
.MODEL FLAT, STDCALL
OPTION CASEMAP: NONE
INCLUDE \MASM32\INCLUDE\WINDOWS.INC
INCLUDE \MASM32\INCLUDE\KERNEL32.INC
INCLUDE \MASM32\INCLUDE\USER32.INC
INCLUDE \MASM32\INCLUDE\COMDLG32.INC
INCLUDELIB \MASM32\LIB\USER32.LIB
INCLUDELIB \MASM32\LIB\KERNEL32.LIB
INCLUDELIB \MASM32\LIB\COMDLG32.LIB

.DATA
MSGCAPTION DB "INFPE",0
MSGBOXTEXT DB "TARGET IS CHANGED",0

PROGSIZE DD PROG_SIZE
MAPSIZE DD PROG_SIZE + 1000H

OFN OPENFILENAME <>
FILTERSTRING DB "EXECUTABLE FILES",0,"*.EXE",0
DB "ALL FILES",0,"*.*",0,0

.DATA?
FILENAME DB 256 DUP ( ? )
FILEHANDLE DD ?
FILESIZE DD ?
H_BUFFER DD ?
M_BUFFER DD ?

.CODE
START:
;________________ _ _ _ [ -CODE____SEC- ] _ _ _ __
MOV OFN.lStructSize,SIZEOF OFN ; OPENFILENAME DIALOG
MOV OFN.lpstrFilter, OFFSET FILTERSTRING
MOV OFN.lpstrFile, OFFSET FILENAME
MOV OFN.nMaxFile,512
MOV OFN.Flags, OFN_FILEMUSTEXIST or \
OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
OFN_EXPLORER or OFN_HIDEREADONLY
INVOKE GetOpenFileName, ADDR OFN

INVOKE _lopen,ADDR FILENAME,OF_READWRITE; READ & WRITE ACCESS
MOV FILEHANDLE,EAX

INVOKE GetFileSize,EAX,NULL ; GET FILESIZE
INC EAX
JZ _EXIT
DEC EAX

MOV FILESIZE,EAX
ADD MAPSIZE,EAX ; MAPSIZE=PROG_SIZE+FILESIZE
; +1000H(EXTRA BUFFER)
INVOKE GlobalAlloc,GHND, MAPSIZE ; ALLOCATE MEMORY
MOV H_BUFFER, EAX ; GHND=ZERO INITIALIZED
; +NON FIXED MEMORY BLOCK
INVOKE GlobalLock,EAX ; LOCK MEMORY BLOCK
MOV M_BUFFER, EAX ; M_BUFFER IS THE RESULTING
MOV EDI,M_BUFFER ; POINTER TO OUR ALLOCATED MEMORY

INVOKE _lread,FILEHANDLE,M_BUFFER,FILESIZE; READ ENTIRE FILE INTO BUFFER
INVOKE _lclose,FILEHANDLE ; CLOSE FILE (???)
; >>>DO SOME CHECKS<<<
CMP WORD PTR [ EDI ], "ZM" ; CHECK FOR 'MZ'
JNZ _EXIT
ADD EDI, [EDI + 03CH] ; EDI=POINTER TO PE HEADER
CMP WORD PTR [ EDI ], "EP" ; CHECK FOR 'PE'
JNZ _EXIT
CMP DWORD PTR [ EDI + 04CH ], 0 ; CHECK IF OTHER OR OUR PROG
JNZ _EXIT ; HAS INFECTED THIS EXECUTABLE
; >>>GET LAST SECTION<<<
MOV ECX, [ EDI + 074H ] ; ECX=NBR OF DATAENTRIES
LEA ECX, [ ECX * 8 + EDI ] ; *8(2 DD'S)+EDI(MAPBASE)
MOVZX EAX, WORD PTR [ EDI + 006H ] ; EAX=WORD PTR [PE_6H](SECTIONNBR)
DEC EAX ; -1
LEA EBX, [ EAX + EAX * 4 ] ; EBX=EAX*28H(SECTION LEN)
LEA EBX, [ EBX * 8 ] ; ...
LEA EBX, [ EBX + ECX + 078H ] ; +ECX+78H(OPTIONAL_HDR LEN)
; >>>CHANGE VIRTUAL SIZE<<<
MOV EAX, PROGSIZE
XADD [ EBX + 008H ], EAX
CMP EAX, [ EBX + 010H ] ; CHECK IF PE IS CORRUPTED
JA _EXIT ; (PE-PACK/UPX/...)

PUSH EAX ; SAVE OLDVIRTUALSIZE

PUSH DWORD PTR [ EBX + 010H ] ; SAVE OLDSIZEOFRAWDATA
; >>>CHANGE SIZE OF RAW DATA<<<
ADD EAX, PROGSIZE ; EAX=NEWVIRTUALSIZE
XOR EDX, EDX ;
MOV ECX, [ EDI + 03CH ] ; ECX=FILEALIGN VALUE
DIV ECX ; EAX=EAX(VIRTUALSIZE)/ECX
INC EAX ; +1
IMUL EAX, ECX ; *ECX
MOV [ EBX + 010H ], EAX ; STORE RESULT TO SIZEOFRAWDATA
; >>>CHANGE SIZE OF IMAGE<<<
POP ECX ; ECX=OLDSIZEOFRAWDATA
MOV EAX, [ EBX + 010H ] ; EAX=NEWSIZEOFRAWDATA
SUB EAX, ECX ; -ECX
ADD [ EDI + 050H ], EAX ; ADD RESULT

OR DWORD PTR [ EBX + 024H ], 0C0000000H; MAKE SECTION READABLE & WRITABLE
MOV DWORD PTR [ EDI + 04CH ], 'ARAS' ; MARK FILE
;
POP EAX ; EAX=OLDVIRTUALSIZE
ADD EAX, [ EBX + 00CH ] ; +VIRTUALADDRESS
XCHG [ EDI + 028H ], EAX ; STORE NEW ENTRYPOINT
ADD EAX, [ EDI + 034H ]

MOV EDI, [ EBX + 014H ] ; EAX=POINTERTORAWDATA
ADD EDI, [ EBX + 008H ] ; EAX=EAX+VIRTUALSIZE
MOV ECX, PROGSIZE
SUB EDI, ECX ; -PROG_LENGHT
ADD EDI, M_BUFFER ; EAX=EAX+MAPOFFSET
MOV ESI, OFFSET PROG_START ; ESI->PROG_BODY
REP MOVSB ; WRITE PROG TO FILEBUFFER

MOV [ EDI - ( PROG_END - HRETURN ) + 1 ], EAX; PUSH OLDEP + IMGBASE / RET

INVOKE _lcreat,ADDR FILENAME,0 ; OVERWRITE FILE...

MOV EAX, [ EBX + 014H ] ; EAX=POINTERTORAWDATA
ADD EAX, [ EBX + 010H ] ; +SIZEOFRAWDATA
;

INVOKE _lwrite,FILEHANDLE,M_BUFFER,EAX ; WRITE BUFFER TO FILE
INVOKE _lclose,FILEHANDLE ; CLOSE FILE
_EXIT:

INVOKE GlobalUnlock,M_BUFFER ; CLOSE ALLOCATED MEMORY BLOCK
INVOKE GlobalFree,H_BUFFER

INVOKE MessageBox, NULL,ADDR MSGBOXTEXT, ADDR MSGCAPTION,0
INVOKE ExitProcess,NULL

;________________ _ _ _ [ -HOST___PROG- ] _ _ _ __
PROG_START: ; <-TRANSFERED LATER ON
PUSHAD

CALL DELTA ; GET DELTA
DELTA: POP EBP
SUB EBP, DELTA

CALL GET_KERNEL ; GET KERNEL BASE

MOV ECX,2 ; HOW MANY KERNEL API'S DO WE
LEA ESI, [ EBP + ___KERNEL32 ] ; WANT? 2 I THINK...
CALL GET_APIS

LEA EAX, [ EBP + _USER32 ] ; GET USER32 BASE VIA LOADLIB
PUSH EAX
CALL [ EBP + _LOADLIBRARY ]

TEST EAX, EAX ; HUH???
JZ ERR_EXT

MOV [ EBP + _DEFAULT ], EAX ; DEFAULT = USER32.DLL

MOV ECX, 1 ; WE ONLY NEED ONE SINGLE USER
LEA ESI, [ EBP + ___USER32 ] ; API (MSGBOX) THIS TIME...
CALL GET_APIS

PUSH 0 ; SAY HELLO...
CALL @F
DB "LITTLE TEST",0
@@: CALL @F
DB "HELLO FROM INFECTED HOST",0
@@: PUSH 0
CALL [ EBP + _MESSAGEBOX ]

ERR_EXT:POPAD ; GET OLD REG VALUES
HRETURN:PUSH DWORD PTR 0 ; ...IS CHANGED LATER!!
RET ; BYYYE

;________________ _ _ _ [ -GET_KERNEL- ] _ _ _ __
GET_KERNEL: ; RETURNS THE KERNEL BASE
MOV ECX, [ ESP + 9 * 4 ] ; SIMPLE BUT SMALL :)
@@: DEC ECX
MOVZX EDX, WORD PTR [ ECX + 03CH ] ; EDX = POINTER TO PE_HDR
CMP ECX, [ ECX + EDX + 034H ] ; COMPARE CURRENT BASE WITH
JNZ @B ; THE KERNEL IMAGE_BASE (MZ)
MOV [ EBP + _KERNEL ], ECX ; STORE RESULT
MOV [ EBP + _DEFAULT ], ECX
RET

;________________ _ _ _ [ -GET_APIS- ] _ _ _ __
GET_APIS: ; SCANS THROUGH API TABLE
INC ESI ; AND RETURNS ADDRESSES
PUSH ECX
CALL GET_API ; SEARCH SINGLE API ADDRESS
POP ECX
MOVZX EBX, BYTE PTR [ ESI - 1 ]
ADD ESI, EBX ; STORE ADDRESS IN THE
MOV [ ESI ], EAX ; API TABLE...
ADD ESI, 4
LOOP GET_APIS ; NEXT ONE
RET

;________________ _ _ _ [ -GET_API- ] _ _ _ __
GET_API: ; SCANS FOR A SINGLE API ADR
MOV EDX, [ EBP + _DEFAULT ] ; EDX = DEFAULT MODULE BASE
ADD EDX, [ EDX + 03CH ] ; + OFFSET PE_HEADER
MOV EDX, [ EDX + 078H ] ; EDX = PTR EXPORT_DIR RVA
ADD EDX, [ EBP + _DEFAULT ] ; + BASE
MOV EDI, [ EDX + 020H ] ; EDI = PTR ADDRESS_OF_NAMES RVA
ADD EDI, [ EBP + _DEFAULT ] ; + BASE
MOV EDI, [ EDI ] ; EDI = PTR ADR_OF_NAMES RVA
ADD EDI, [ EBP + _DEFAULT ] ; + BASE
MOV EAX, [ EDX + 018H ] ; EAX = NUMBER_OF_NAMES
XOR EBX, EBX
NXT_ONE:INC EBX
MOVZX ECX, BYTE PTR [ ESI - 1 ] ; LENGHT OF SPEZIFED API NAME
PUSH ESI
PUSH EDI
REPZ CMPSB ; COMPARE API NAME WITH
POP EDI ; EXPORT ENTRY
POP ESI
JZ FOUND
PUSH EAX
XOR AL, AL
SCASB ; GET NEXT ONE
JNZ $ - 1
POP EAX
DEC EAX ; DECREASE NUMBER_OF_NAMES
JZ ERR_EXT
JMP NXT_ONE
FOUND: MOV ECX, [ EDX + 024H ] ; ECX = PTR NBR_NAME_ORDS RVA
ADD ECX, [ EBP + _DEFAULT ] ; + BASE
DEC EBX
MOVZX EAX, WORD PTR [ ECX + EBX * 2 ] ; EAX = ORDINAL OF FUNCTION
MOV EBX, [ EDX + 01CH ] ; EBX = PTR ADR_OF_FUNCTIONS RVA
ADD EBX, [ EBP + _DEFAULT ] ; + BASE
MOV EAX, [ EBX + EAX * 4 ] ; EAX = FUNCTION RVA!!!!
ADD EAX, [ EBP + _DEFAULT ] ; + BASE
RET

;________________ _ _ _ [ -API_TAB- ] _ _ _ __
___KERNEL32: ; KERNEL APIS, YOU CAN ADD AS
db 11,"LoadLibrary" ; MANY AS YOU WANT BUT DON'T FORGET
_LOADLIBRARY dd 0 ; TO CHANGE THE API-NUMBER ABOVE
db 11,"ExitProcess" ; BEFORE MAKING THE CALL TO GET_APIS
_EXITPROCESS dd 0


___USER32: ; USER32 API'S
db 10,"MessageBox" ;
_MESSAGEBOX dd 0

;________________ _ _ _ [ -DATA- ] _ _ _ __
_KERNEL dd 0 ; ...
_USER32 db "User32",0
_DEFAULT dd 0

PROG_END:

PROG_SIZE EQU $ - PROG_START

END START
Posted on 2001-12-13 14:37:38 by mob