Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 01-22-2005, 09:20
Flagmax
 
Posts: n/a
Armadillo crashes Olly

Hi all,

Maybe this is old news but I think it might help the new guys as it helped me.

As some of us know, Armadillo uses OutputDebugStringA() which sends a badly formatted message causing Ollydbg to crash. Perhaps this will be taking care of in the next version of Olly but until then here is what I got to share.

First here is the code where Olly crashes
Code:
0042E125    8B45 0C               MOV EAX,DWORD PTR SS:[EBP+C]             ; Moves Address where deadly msg is to EAX
0042E128    50                    PUSH EAX                                 ; Push this address on Stack
0042E129    8D95 FCEDFFFF         LEA EDX,DWORD PTR SS:[EBP-1204]
0042E12F    52                    PUSH EDX
0042E130    E8 1F8B0700           CALL OLLYDBG.004A6C54                    ; Inside this call is where Olly dies
So at the location of the Call that kills Olly I make it Call my "Check for bad message function" that I placed in the EXE"
Code:
0042E130    E8 9193FEFF           CALL OLLYDBG.004174C6                    ; Now Call my routine to Fix deadly msg
Now here is my Function
Code:
004174C6    8138 44656275         CMP DWORD PTR DS:[EAX],75626544          ; Check if it's the deadly message "Debug string: %s%s%s%s%s%s%s%s%s%s%s%..."
004174CC    75 07                 JNZ SHORT OLLYDBG.004174D5               ; If its not, Jump Over Fix
004174CE    C740 0E 4F4B0000      MOV DWORD PTR DS:[EAX+E],4B4F            ; Fix by making message say "Debug string: OK"
004174D5    E9 7AF70800           JMP OLLYDBG.004A6C54                     ; Jump to the location where the original Call goes
I placed it here because it looks like Olly don't use this space for anything, padded zero's. If you haven't noticed it, this is my second version of patcher. At first I only compared for the known bad message "%s%s%s..." that Armadillo makes but it can be varied slightly like "%shehe%s..." or "%schad%rules..." which will also Kill Olly so I decided to stop all messages from this API. Now I search for "Debu" and if found, replace with "Debug string: OK" which Olly has no probs with. This is message you see in Olly. Be advised that this fix pretty much disables this API but as long as we can unpack Armadillo we're happy

Since I have 10+ post I can now thank people

Big thanks goes to gabri3l who was able to find the cause of crash. Also to diablo2oo2 for his Universal Patcher (dUP) that I used and Author of Ollydbg.
And everyone in this thread hxxp://www.woodmann.com/forum/showthread.php?t=6153

I hope somr people will learn from this,
Have a great day,
Flagmax.
Attached Files
File Type: rar Ollydbg1.10patch1.2.rar (3.5 KB, 52 views)
Reply With Quote
  #2  
Old 01-22-2005, 15:49
JuneMouse
 
Posts: n/a
well i saw a crackme that was crashing ollydbg this way

the crakme is here
http://biw.rult.at/vbb/upload/showthread.php?threadid=1042

so i kinda modified ollydbg to prevent it from crashing

Code:
########################################################################################################################################################
DO NOT USE WORD WRAP IN NOTEPAD AND MAXIMIZE SCREEN FOR BETTER VIEWABILITY
########################################################################################################################################################

here is the modification i did to ollydbg

004AF644    > \60              PUSHAD                             ;  well safety
004AF645    .  6A 03           PUSH    3                           ;  MEM_RESILENT I THINK NOT SURE COPY PASTE 
004AF647    .  FF35 26574D00   PUSH    DWORD PTR DS:[4D5726]       ;  poked around  and saw olly using it so i am using it
004AF64D    .  FF35 20574D00   PUSH    DWORD PTR DS:[4D5720]       ;  poked around  and saw olly using it so i am using it
004AF653    .  52              PUSH    EDX                         ;  poked around  and saw olly using it so i am using it
004AF654    .  E8 B31CFBFF     CALL    OLLYDBGm._Readmemory        ;  what else reading memory
004AF659    .  B8 25000000     MOV     EAX, 25                     ;  set % as scan charecter
004AF65E    .  8B3C24          MOV     EDI, DWORD PTR SS:[ESP]     ;  you might have noticed i have not popped up stack 
004AF661    .  8B4C24 08       MOV     ECX, DWORD PTR SS:[ESP+8]   ;  you might have noticed i have not popped up stack 
004AF665    .  F2:AE           REPNE   SCAS BYTE PTR ES:[EDI]      ;  scanning for % in the debugstring 
004AF667    .  83F9 00         CMP     ECX, 0                      ;  will be zero only if the string didnt contain % 
004AF66A    .  75 0E           JNZ     SHORT OLLYDBGm.004AF67A     ;  bad boy 
004AF66C    .  83C4 10         ADD     ESP, 10                     ;  popping stack contents of ReadMemory call
004AF66F    .  61              POPAD                              ;  safety relese
004AF670    .  E8 B775FFFF     CALL    OLLYDBGm.004A6C2C           ;  restore old instruction that was buggered up for this check and call it 
004AF675    .^ E9 141CF8FF     JMP     OLLYDBGm.0043128E           ;  jmp back to original place
004AF67A    >  83C4 10         ADD     ESP, 10                     ;  popping up stack contents of Readmemory
004AF67D    .  61              POPAD                               ;  safety release
004AF67E    .  83C4 08         ADD     ESP, 8                      ;  popping the original args
004AF681    .^ E9 CD1CF8FF     JMP     OLLYDBGm.00431353           ;  jmping to readmemory failure place 


######################################################################################################################################################

this is the call i am diverting to my modification 
######################################################################################################################################################

00431289    . /E9 B6E30700     JMP     OLLYDBGm.004AF644

######################################################################################################################################################
the above is my code what i did was to parse the string any string that conmes to this place for % specifier if it existed it will not output that string
if it didnt exist it will output that string

hope it may be of help to some one can some one test this on armadillo and tell me whether it works properly i know it works on this crackme
ollydbg version 1.10
tested on w2k sp4
any other test reports on different os are also appreciated

Last edited by JuneMouse; 01-22-2005 at 17:08.
Reply With Quote
  #3  
Old 01-22-2005, 21:15
MaRKuS-DJM's Avatar
MaRKuS-DJM MaRKuS-DJM is offline
Cracker + Unpacker
 
Join Date: Aug 2003
Location: Virtual World / Network
Posts: 553
Rept. Given: 7
Rept. Rcvd 6 Times in 4 Posts
Thanks Given: 3
Thanks Rcvd at 16 Times in 10 Posts
MaRKuS-DJM Reputation: 6
really nice patch working on Windows XP Professional SP2.
will pack this patched OllyDbg.exe in my zip.
but does anyone know why olly crashes at this message?
Reply With Quote
  #4  
Old 01-22-2005, 21:29
TQN TQN is offline
VIP
 
Join Date: Apr 2003
Location: Vietnam
Posts: 358
Rept. Given: 143
Rept. Rcvd 24 Times in 13 Posts
Thanks Given: 196
Thanks Rcvd at 168 Times in 51 Posts
TQN Reputation: 24
As Flagmax said: hxxp://www.woodmann.com/forum/showthread.php?t=6153
A patch to OllyDbg is good, but we have many patches for OllyDbg. One for hide OllyDbg with Toolhelp API, one for protect OllyDbg with OutputDebugString (and will have another patch ...?) Can we write a plugin to apply the patch automatically to OllyDbg when OllyDbg start ? Can we use AppInit key ?
Regards

Last edited by TQN; 01-22-2005 at 21:31.
Reply With Quote
  #5  
Old 01-22-2005, 22:44
D-Jester's Avatar
D-Jester D-Jester is offline
VIP
 
Join Date: Nov 2003
Location: Ohio, USA
Posts: 269
Rept. Given: 39
Rept. Rcvd 61 Times in 41 Posts
Thanks Given: 0
Thanks Rcvd at 4 Times in 4 Posts
D-Jester Reputation: 61
According to CERT this is a security flaw that was found in late July, 2004

http://www.us-cert.gov/cas/bulletins/SB04-217.html

<-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=->

Vendor & Software Name : OllyDbg version 1.10

Vulnerability - Impact : Denial of Service vulnerability exists that could allow an attacker to crash OllyDbg and execute machine code. This vulnerability is due to a format string bug in the code that handles Debugger Messages.

Patches - Workarounds : No solution is available at this time.

Attacks Scripts : A working exploit has been published.

Common Name : OllyDbg Format String Bug

Risk : High

Source : SecuriTeam, July 20, 2004

<-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=->

So it was a published exploit after the final release of 1.10, which was released June 11, 2004

Hopefully its fixed in 2.x

Peace...
__________________
Even as darkness envelops and consumes us, wrapping around our personal worlds like the hand that grips around our necks and suffocates us, we must realize that life really is beautiful and the shadows of despair will scurry away like the fleeting roaches before the light.
Reply With Quote
  #6  
Old 01-22-2005, 23:15
deXep deXep is offline
Friend
 
Join Date: Aug 2004
Posts: 42
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 0
Thanks Rcvd at 0 Times in 0 Posts
deXep Reputation: 0
it seems u can try to kill all "%" char...
Reply With Quote
  #7  
Old 01-23-2005, 03:39
Flagmax
 
Posts: n/a
Hi JuneMouse,

That some advanced patch you got Looks like you don't like 25 (%) hehe Reason I say that is it looks to me you're searching on the stack through 139853913 bytes to find it. If Any 25 found, the you take drastic majors I don't think it actually finds that bad %s%s%s... but some other 25 could be of an address or something else. But it does the job

I ran that crackme and it sure does use same string format vulnerability as does Armadillo. Wish it was more unique like %sBad%sC%Bad%s though. I tried your patch and it works with Armadillo just fine. Oh and my patch works with that Crackme

MaRKuS-DJM:
Very good article here about the cause. hxxp://www.cs.ucsb.edu/~jzhou/security/formats-teso.html

TQN:
Where are the other patchers? I want them all

deXep:
That is what I kinda do, but you only need to kill the first %s for it to work. Olly copies the string until it reaches two null charecters 00,00 then it stops. So no reason to kill all of them. Actually it has no problems with % at all, you can put as many you like, its the %s folowed by another %s that causes chaos. %s is is used in 'C' programming language to handle Strings.


NOTE: The patch will make a backup of your Ollydbg.exe into Ollydbg.bak but as soon as you start Ollydbg it will overwrite this file with its own so its best that you rename or backup yourself if you ever decide you don't like the patch.

Last edited by Flagmax; 01-26-2005 at 08:09.
Reply With Quote
  #8  
Old 01-23-2005, 16:33
upb's Avatar
upb upb is offline
Friend
 
Join Date: Apr 2002
Location: Elbonia
Posts: 63
Rept. Given: 5
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 3
Thanks Rcvd at 0 Times in 0 Posts
upb Reputation: 0
the ROOT cause of this problem is that olly must be using a *printf* function and supply the debug string as the FORMAT parameter. while it should supply "%s" as the format parameter and the debug string as additional param. so maybe somene with a little bit of free time can find this place in olly and patch it.
Reply With Quote
  #9  
Old 01-23-2005, 19:06
JuneMouse
 
Posts: n/a
well oleh is using Message(debugstring);
instead of Message(%s,debugstring);
to sprintf() before his addtolist()
i didnt look into it deep i was satisfied when the crackme stopped crashing ollydbg
but
Flagmax why do you say it looks at so much bytes there is a parameter number of bytes to read that is passed to Readmemory() it gets filled up before i call it

Quote:
004AF647 . FF35 26574D00 PUSH DWORD PTR DS:[4D5726] ; poked around and saw olly using it so i am using it
004AF64D . FF35 20574D00 PUSH DWORD PTR DS:[4D5720] ; poked around

the read memory reads only that much bytes and as far as i noticed it sets the nullterminator too i think after it uses ReadProcessMemory() api

and i use that same value for repnesacsb
Quote:
004AF661 . 8B4C24 08 MOV ECX, DWORD PTR SS:[ESP+8] ; you might
can you tell me if you single stepped through and tell me if that length value was initialised or not
any way thanks for making it into a usable patch (i didnto try it coz i cant download) but hope you made it good
and thanks to markus for trying it out on xp-sp2 and liking it

the othere patches that TQN refers is in rce forum posted by shub-Nigurrath
it is about changing the ollydbg class string and window text so that it can evade the crop of FindWindow() Coders
Reply With Quote
  #10  
Old 01-24-2005, 01:09
Crk
 
Posts: n/a
can we have a patch that does all the work?? applying different patches could cause problem or maybe an additional bug on Olly

Regards
Reply With Quote
  #11  
Old 01-24-2005, 09:49
Flagmax
 
Posts: n/a
JuneMouse:

I am no expert but here is what I came up with.

Your patch behaves differently with Armadillo, it actually would fail.

It seems in works great with BrainCell and Python24, but with Armadillo its another story.

Below is the Case with Armadillo.

Inside this call:
004AF654 E8 B31CFBFF CALL OLLYDBG_._Readmemory
Olly uses ReadProcessMemory() to Read the chunk of memory.
...
0046142B E8 3EDD0400 CALL <JMP.&KERNEL32.ReadProcessMemory>
The ReadProcessMemory() is setup with the parameters below. So you see it tries to Read 8560059h bytes
from 0100EF70h to 0012F340h.
Code:
0012CC24   000000BC  |hProcess = 000000BC
0012CC28   0100EF70  |pBaseAddress = 0100EF70 - This is good offset: Debug message is here
0012CC2C   0012F340  |Buffer = 0012F340
0012CC30   08560059  |BytesToRead = 8560059 (139853913.)
0012CC34   00000000  \pBytesRead = NULL
But my findings is it Fails on Reading the memory. It is possible because VirtualProtect is not setup
correctly or maybe hProcess is wrong. So you have a good idea but it is not accomplished in this case.

Then we get to your Search routine.
REPNE SCAS uses the same parameters as ReadProcessMemory. This is where it Scans so many bytes, Buffer at 0012F340h and
length is 8560059h. You can press F7 at 004AF665h and see it Scan and ECX decreasing.
Code:
004AF65E    8B3C24              MOV EDI,DWORD PTR SS:[ESP]               ; Set EDI with Start of buffer
004AF661    8B4C24 08           MOV ECX,DWORD PTR SS:[ESP+8]             ; Set length of bytes to Search in ECX
004AF665    F2:AE               REPNE SCAS BYTE PTR ES:[EDI]             ; Scan for 25h in Buffer
004AF667    83F9 00             CMP ECX,0                                ; If ECX = 0 then it reached to End of buffer
Now since Readmemory FAILED, you are searching who knows what, the Debug Message is no where in this buffer.

In my case it found 25h at 0012FB9Ah and look whats that 25h part of:
0012FB98 |7C92 25 38 UNICODE "kernel32.dll"

So you see the problem is with ReadProcessMemory(). So I believe if the buffer(Stack) didn't have this or other 25 then
your patch would not work with Armadillo.

Maybe someone can verify this.
Steps:
1. Open First Ollydbg
2. Now Open Second Olly that been patched with JuneMouse from within First Olly
3. Place a breakpoint at 004AF654, you should see CALL OLLYDBG_._Readmemory there.
4. Now Press F9 and you should see Second Olly in Taskbar.
5. Switch to Second Olly and Open then Run some Armadillo target that uses OutputDebugStringA()
6. Shortly First Olly should Break at 004AF654.
7. Now Press F7 to go into that Call and Scroll down to 0046142B: E8 3EDD0400 - CALL <JMP.&KERNEL32.ReadProcessMemory>
8. Place a Breakpoint there and press F9, once it stops here press F8 and look at the EAX, if it 0, then the Read Failed, 1 = Successful.

Last edited by Flagmax; 01-24-2005 at 10:24.
Reply With Quote
  #12  
Old 01-24-2005, 19:22
JuneMouse
 
Posts: n/a
FlagMax
well if it failed in ReadProcessMemory() then probably this patch can be modified
to test for the Result and take Appropriate action as i said i did not look
deep into it and didnot test it wtih any other application apart from that
crackme and some masm code i cooked up for testing it

Code:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

.data
MsgBoxText      db "Win32 Assembly is Great!",0
vulnstring      db "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
                   db "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
                   db "%s%s%s%s%s%s%s%s%s%s%s%s ",0

.code
start:
      invoke OutputDebugString,addr MsgBoxText
      invoke OutputDebugString,addr vulnstring
      invoke ExitProcess,NULL
end start
but could youtell me the arguments that are passed here
Code:
004AF654    .  E8 B31CFBFF     CALL    OLLYDBGm._Readmemory        ;  what else reading 
like this 
0012DA60   004AF659  RETURN to OLLYDBGm.004AF659 from OLLYDBGm._Readmemory
0012DA64   0012F340
0012DA68   00403000  OLLYDBGm.00403000
0012DA6C   00000019
0012DA70   00000003

this is from the test code i posted above assembled in qeditor and using hutch masm
buildall in project 
the exact Readmemory stack details

0012CC20   00461430  /CALL to ReadProcessMemory from OLLYDBGm.0046142B
0012CC24   00000100  |hProcess = 00000100 (window)
0012CC28   00403000  |pBaseAddress = 403000
0012CC2C   0012F340  |Buffer = 0012F340
0012CC30   00000019  |BytesToRead = 19 (25.)
0012CC34   00000000  \pBytesRead = NULL
Quote:
It is possible because VirtualProtect is not setup
correctly or maybe hProcess is wrong
regarding hProcess you can open view handles window and look at the handle
details (expand the columns to make visible hidden details)
Handles, item 63
Handle=00000100
Type=Process
Refs= 8.
Access=0002047B READ_CONTROL|QUERY_STATE|MODIFY_STATE|478
T=*

or use processexplorernt from sysinternals and corelate them
like this
Process formatprob.exe(480) 0x100 0x0002047B

hope you can provide some more deatils so that this can be made properly
any way thanks for feedback
Reply With Quote
  #13  
Old 01-25-2005, 02:36
Flagmax
 
Posts: n/a
This is the arguments I get when running Armadillo target. As you can see the length is really large and its the same in two times Armadillo call OutputDebugString(). So I think they key is to find out where and why this number is not set to the actual message length.

0012DA60 004AF659 RETURN to OLLYDBG_.004AF659 from OLLYDBG_._Readmemory
0012DA64 0012F340
0012DA68 0100EF70
0012DA6C 08560059
0012DA70 00000003



Quote:
Originally Posted by JuneMouse
but could youtell me the arguments that are passed here
[code]
004AF654 . E8 B31CFBFF CALL OLLYDBGm._Readmemory ; what else reading
like this
Reply With Quote
  #14  
Old 01-25-2005, 04:26
Flagmax
 
Posts: n/a
Problem Solved...

Hi JuneMouse,

I did more tracing and found the root cause of the problem. It seems in this Armadillo, the address that holds the length of message also gets filled up with some junk. And in your patch you are Pushing DWORD to the stack. Instead you need to push just a WORD. The Code here shows the proper way:
Code:
00431294    0FB71D 26574D00     MOVZX EBX,WORD PTR DS:[4D5726]           ; Copies just a WORD
...
00431336    53                  PUSH EBX                                 ; Push Length to Stack
00431337    A1 20574D00         MOV EAX,DWORD PTR DS:[4D5720]
0043133C    50                  PUSH EAX
0043133D    8D95 98FDFFFF       LEA EDX,DWORD PTR SS:[EBP-268]
00431343    0355 F4             ADD EDX,DWORD PTR SS:[EBP-C]
00431346    52                  PUSH EDX
00431347    E8 C0FF0200         CALL OLLYDBG_._Readmemory                ; Read a Chunk of Memory
Oh so here is a minor fix that I made. Now I believe its 100% working.
Code:
004AF644    60                  PUSHAD
004AF645    6A 03               PUSH 3
004AF647    0FB71D 26574D00     MOVZX EBX,WORD PTR DS:[4D5726]           ; Copies a WORD from 4D5726h and strips the rest junk
004AF64E    53                  PUSH EBX                                 ; Now Push the correct Length of Message to Stack
004AF64F    FF35 20574D00       PUSH DWORD PTR DS:[4D5720]
004AF655    52                  PUSH EDX
004AF656    E8 B11CFBFF         CALL OLLYDBG_._Readmemory
004AF65B    B8 25000000         MOV EAX,25
004AF660    8B3C24              MOV EDI,DWORD PTR SS:[ESP]
004AF663    8B4C24 08           MOV ECX,DWORD PTR SS:[ESP+8]
004AF667    F2:AE               REPNE SCAS BYTE PTR ES:[EDI]
004AF669    83F9 00             CMP ECX,0
004AF66C    75 0E               JNZ SHORT OLLYDBG_.004AF67C
004AF66E    83C4 10             ADD ESP,10
004AF671    61                  POPAD
004AF672    E8 B575FFFF         CALL OLLYDBG_.004A6C2C
004AF677  ^ E9 121CF8FF         JMP OLLYDBG_.0043128E
004AF67C    83C4 10             ADD ESP,10
004AF67F    61                  POPAD
004AF680    83C4 08             ADD ESP,8
004AF683  ^ E9 CB1CF8FF         JMP OLLYDBG_.00431353

Last edited by Flagmax; 01-26-2005 at 08:10.
Reply With Quote
  #15  
Old 01-25-2005, 18:14
JuneMouse
 
Posts: n/a
Quote:
0012DA68 0100EF70
does this address hold the debugstring that is passed from armadillo
use follow in dump or use ctrl+g and type the address and go there and look
if yes does the length match to the word ptr in that is it 0x59 bytes long string ???
Quote:
0012DA6C 08560059
if the above is valid then i would assume pushing the word ptr content is acceptable

but i think olly originally pushes dword (ill check it later) and it fetches the length from an earlier ReadMemory() or ReadCommand() or Find Ref() code
so

also could you please assemble the code i posted above and check it too
the first param length is 0x 19 and the second param length is 0x 5b
in my code
also if youare pushing word then i would suggest you to do an equivalent to this in windows
for i in `seq 1 65540`; echo -n A >> test.txt (this in bash would create a file test.txt containing AAAAAAAAAAAAAAAA 65540 times
i dont know if windows echo supports it i think you have to write a bat file
with for and execute it to make this dummy file
and then use the bintodb.exe in the masm package and use it to assemble the code

put those dbs here
vulnstring db "65,65,65,65,65,65
db "65,65,65, for 65540 times so that the length crosses the word barrier so that we can deduce if such a long string will still work or not as it is expected to work or still crashes on other bugs or overflows

any way if you say the patch works fine with your modification on all targets
it think it is still fine
some thing is better than nothing
thanks once again
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
help unpacked .dll now crashes Mitchjs General Discussion 3 04-28-2008 07:41
Armadillo 4.42 & Olly TmC General Discussion 1 04-23-2006 09:22
Ida2Sice crashes Softice?! bEaST General Discussion 0 09-07-2005 22:17
OllyScript 0.85 and Olly 1.10 crashes ??!? Shub-Nigurrath General Discussion 6 07-11-2004 19:10


All times are GMT +8. The time now is 18:17.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )