Page 2 of 2 FirstFirst 12
Results 16 to 30 of 30

Thread: Harlequins Task 3 Challenge

  1. #16
    Hi Kayaker,

    My reversed and recoded version of Harlequin's crackme is coming along quite well, but there is one silly little bug that is driving me crazy. ...And that's the Bitmap resource.

    Now, I could easily load the bitmap using LoadBitmap() and then paint it into the client area by getting a device context and using BitBlt() in response to the WM_PAINT message... BUT I'm trying to keep this as "authentic" as possible and thats clearly not what Harlequin did to load his Bitmap (as evidenced by the imports in WDASM).
    Indeed, there appear not to be any GDI functions of any kind. So I'm presuming that there is some way to load the bitmap direct via the resource file ??? I've examined the resource file from Harlequin's crackme in detail and I just can't quite seem to figure it out... I don't even see any mention of the Bitmap's resource identifier in my dead listing. Admittedly my Win32 asm programming skills are limited, but I'm unsure how load this thing w/o any GDI APIs. Likely, there is some insanely simple way to do this and I'm going to shoot myself in the foot for asking about it when I find out... but a little insight will be appreciated anyway ;-)

    Thanks :-)
    Clandestiny

  2. #17
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,146
    Blog Entries
    5
    Hi Clandestiny,

    I had a bit of a problem with that one too. Working with .rc files is still a bit of a black art

    I extracted the .bmp and .ico with ResHacker and produced an .rc file from the original exe with BRW. After the usual messing around to get MASM to recognize it, I had the same problem with no bmp in the static edit control. Finally got it right:

    ======================================
    #include "resource.h"

    #define BITMAP_1 104
    #define IDC_EDIT_REG 107
    #define IDC_BUTTON 108

    BITMAP_1 BITMAP "Harl.bmp"

    ICON_1 ICON "Harl.ico"

    100 DIALOG 0, 0, 128, 105
    EXSTYLE 0x200L
    STYLE DS_ABSALIGN | 0xA04L | WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    CAPTION " "
    FONT 8, "Times New Roman"
    BEGIN
    CONTROL "", 102, "STATIC", SS_BLACKRECT | WS_CHILD | WS_VISIBLE, 0, 0, 131, 137
    CONTROL "Try It!", 108, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 1, 90, 124, 12, 0x200L
    CONTROL "", 101, "EDIT", ES_CENTER | ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER, 1, 35, 124, 38, WS_EX_NOPARENTNOTIFY
    CONTROL "Your Serial", 107, "EDIT", ES_CENTER | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 1, 75, 124, 10
    CONTROL 104, 106, "STATIC", SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZEIMAGE | WS_CHILD | WS_VISIBLE, 1, 3, 124, 28
    END
    =====================================

    Then I used a standard modal dialog template from Iczelion's ASM tut #10-2, and filled in a few of the apparent calls in Harlequin's app within this framework:

    ====================================
    .386
    .model flat,stdcall
    option casemap:none
    DlgProc PROTO : DWORD,: DWORD,: DWORD,: DWORD
    include \masm32\include\windows.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

    .data?
    hInstance HINSTANCE ?

    .const
    MYDIALOG equ 100

    .code
    start:
    invoke GetModuleHandle, NULL
    mov hInstance,eax
    invoke DialogBoxParam, hInstance, MYDIALOG, NULL, ADDR DlgProc, NULL
    invoke ExitProcess,eax

    DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    .IF uMsg==WM_DESTROY || uMsg==WM_CLOSE
    invoke EndDialog, hWnd, 0
    invoke ExitProcess,0

    .ELSEIF uMsg==WM_COMMAND

    .ELSEIF uMsg==WM_INITDIALOG

    .ENDIF

    xor eax,eax
    ret
    DlgProc endp

    end start
    ====================================

    The above code produces a dialog virtually identical to the original, just needs the details filled in now

    Kayaker

  3. #18
    Hi Kayaker,

    Thanks for the pointer. I had no idea you could load a bitmap in the resource file like that. Sure is handy though... and to think I've been writing all that extra code to paint bitmaps into a window's client area for nothing... Likewise, I'm glad I decided to write this in asm since I found out that Borland's Resource Workshop beats VC++'s by a long shot

    Right now I've got the reconstructed program and its working great minus SMC. I don't suppose you know anything about writing SMC, Kayaker ?? ;-)

    Cheers,
    Clandestiny

  4. #19
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,146
    Blog Entries
    5
    Hi Clandestiny,

    Just been thinking about posting an update myself. I'm at the same stage. I'm leaving the final SMC details until I finish, er, "enhancing" the proggy with a new protection

    There's 2 tricky sections I see, one SMC, the other I guess you could call obfuscation. BTW, I actually goofed in my earlier post thinking the line
    :0040108E 66837D106C cmp word ptr [ebp+10], 006C
    was part of SMC code. The obfuscated section is just above it and I had done a screendump in SoftIce of this section and SI didn't parse the code correctly. WDasm does show it properly however.


    Anyway, the obfuscated (that word really doesn't roll of the tongue easily code is at:

    :00401079 6880000000 push 00000080
    :0040107E 6835674000 push 00406735
    :00401083 FF35AB214000 push dword ptr [004021AB]
    :00401089 0000000000 BYTE 5 DUP(0)

    This code is never called. If you look down a little further you see the PUSHes repeated with an indirect call to GetWindowTextA:

    :004010A4 B8E4114000 mov eax, 004011E4
    :004010A9 6880000000 push 00000080
    :004010AE 6827214000 push 00402127
    :004010B3 FF35AB214000 push dword ptr [004021AB]
    :004010B9 FFD0 call eax ;GetWindowTextA

    And 4011E4 is the address of the jump table entry for this API:

    * Reference To: USER32.GetWindowTextA, Ord:0000h
    |
    :004011E4 FF2584304000 Jmp dword ptr [00403084]


    So what I've got right now is a direct Invoke of GetWindowTextA at 401089 so the API will be included in the import table. Then I guess the trick is to hex edit it out later and include the code which will call it indirectly.

    ...continued...

  5. #20
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,146
    Blog Entries
    5
    The SMC is of course right below the obf. section:

    :004010BB 813D272140004F4F7073 cmp dword ptr [00402127], 73704F4F
    :004010C5 B8D0104000 mov eax, 004010D0
    :004010CA C7000F84B600 mov dword ptr [eax], 00B6840F
    :004010D0 C7000F840000 mov dword ptr [eax], 0000840F

    which converts to the proper code of:

    :004010BB 813D272140004F4F7073CMP DWORD PTR [00402127],73704F4F
    :004010C5 B8D0104000 MOV EAX,004010D0
    :004010CA C7000F84B600 MOV DWORD PTR [EAX],00B6840F
    :004010D0 0F84B6000000 JZ 0040118C ;good boy MessageBox

    Sooo, I guess 4010D0 is the line to change, the next line has the bytes to move there, and the original 4010D0 is just bogus, but holds a place for 6 bytes. The tricky part seems to be planning and thinking ahead and knowing what bytes will create the code line you want. I guess the 'a' command in SI is handy for this.

    I don't know, I've never created SMC before. Maybe someone who's played with this can give us a few pointers. Hell, this'd be a great topic in itself.

    Unless you change the code characteristics in the compiled file later, you need to include this in your linker line:
    /SECTION:.text,EWR
    This will create a .text section with the characteristics E0000020, which will allow the SMC to write to memory without crashing.


    BTW, how did you deal with the wm_command loop? In the original file, the loop continues, somewhat ungracefully, after the good message box, which is why you see it flickering. The reason for this I think is that there are *2* wm_command messages processed for every letter you input in the edit box. I've got a little proggy (ISpy) that monitors windows messages and tells me this. In my version the loop finishes with a crash I added a flag which tests if the good messagebox has been called, in which case stop processing messages from that edit box. This works great, but isn't how the original code ran.

    So where the heck is everybody else? They're missing all the good, clean fun ^_^

    Cheers,
    Kayaker

  6. #21
    Hiya Kayaker,

    I think I figured out SMC and its not half as bad as the horrors I'd conjured up in my imagination prior to trying it. In fact, its really cool (and amazing) to me that you can actually do something like this with asm.

    Here's the little piece of SMC I've managed to write so far...

    Test1:
    mov edi,offset smc1 ; define the beginning address of the code you want to replace
    mov [edi],byte ptr 080h ;replace code w/ hex opcodes for new instructions
    inc edi
    mov [edi],byte ptr 0F3h ;replace code
    inc edi
    mov [edi],byte ptr 0D2h ;replace code
    smc1: xor bl,0DCh

    /*********************************
    xor bl,0DCh is a 3 byte instruction and we replaced it with a 3 byte instruction
    xor bl,02Ch
    **********************************/

    mov edi,offset smc2 ;address of code we want to replace
    mov [edi],dword ptr 04E8C166h ;replace code
    smc2: cmp ax,03330h
    xor ebx,ebx
    mov esi, offset serial
    .
    .
    .
    /*********************************
    Here we replace a 4 byte instruction cmp ax,03330h with another 4 byte instruction shr al,04
    *********************************/

    So from this I've deduced a general procedure...

    1) Define a label where you want your SMC to start and load the address of that location in a register
    2) Determine the number of instructions you want to replace and calculate the total number of bytes used by those executable instructions
    3) Load in the new instructions starting at the address you defined to be the beginning of the SMC code until you've reached the total number of bytes of the instructions you've designated for replacement
    4) Change the section characteristics to E0000020h (like you mentioned previously)

    Well, thats all I've discovered so far, but I think it will be servicable for the task at hand

    Oh, and in case you're interested I'll post the urls to the 2 documents I managed to dig up to help me figure this out (though IMO they're a bit skimpy on the explanation).

    http://blacksun.box.sk/smc.txt
    http://www.geocities.com/SiliconValley/2151/selfmod.html

    Just don't get too excited and go overboard with the SMC in your "enhanced" protection, Kayaker ;-)

    Cheers,
    Clandestiny

  7. #22
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,146
    Blog Entries
    5
    Hi Clandestiny,

    I liked your idea of using the OFFSET of the label of the line which is to be SMC'ed in ASM code. Saves having to input it or hexedit it in later once all the coding is finalized.

    In the 2nd step however you still have to manually calculate the opcode and displacement bytes and MOV them as a hex value. I wanted to see if this could also be done entirely as ASM coding and came up with this.

    If you know the conditional jump you want is going to be a Short jump (less than 128 (80h) bytes, then the opcode is one byte long (74h for a JZ). If >80h bytes then it's a 2 byte Near jump opcode (0F84h for JZ). So, that's at least one step that can be hard coded.

    The other bit is the displacement value of the jump. For a Short jump it's 1 byte long, i.e. 00 to 7F. For a Near jump it can be up to 4 bytes long. If you set a label where you want to jump to, i.e a MessageBox, then you can use OFFSET again to calculate the displacement of the jump.

    I wrote a little proggy with source that I'll attach that shows this for both Short and Near jumps.


    The idea is sort of:

    -------------------------------------------------------------------

    mov eax, offset SMC line
    mov ebx, offset Line to jump to

    ;#bytes between start of SMC line and where to jump to
    sub ebx,eax

    ;mov 74h Short jump opcode to first byte of SMC line
    mov byte ptr[eax],74h

    ;compensate 2 bytes for a short jump since jump actually takes place at the END of the line
    sub ebx,2

    ;set pointer to where displacement byte goes
    inc eax

    ;mov displacement bytes into position
    mov [eax],ebx

    ;SMC JZ line now fully produced

    ------------------------------------------------------------------

    And no, I wasn't planning on using this in the "enhanced" version

    Cheers,
    Kayaker

  8. #23
    Kayaker (05-31-2001 00:48):
    In the 2nd step however you still have to manually calculate the opcode and displacement bytes and MOV them as a hex value. I wanted to see if this could also be done entirely as ASM coding and came up with this.
    Hi Kayaker,

    That was a very clever idea with the JMP and thanks for going to the trouble to write me up an example In your example you were writing into an empty section of code and it worked perfectly, but when overwriting some existing code I think there could still be some problems. I think you'd still have to manually calculate opcode lengths for both the inserted instructions and the overwritten instructions to make sure they both fall on the same instruction boundary. Else the remainder of the code will likely be transformed into garbage (as I've had the pleasure to witness quite a few times now Likewise, I've seen my valuable data in one of the registers modified more than once by garbage instructions. It seems one has to be VERY careful about which registers are modified, keeping the meaningful values in the calcuation separate from the bogus ones in the routine. Inserting an SMC instruction or 2 seems not to be too hard, but have you tried a whole block of em? And IMO, you need a whole block of interlaced SMC / real instructions for some meaningful obsfucation Man, I'll tell you right now its a painful coding job and I haven't met with much success... err, I mean it crashes every time I try to run it with more than just a few SMCed lines... I guess I just don't fully grasp the technique yet... And its shattering my delusions of grandeur for pages and pages of SMC obsfucating my "enhanced" protection ;-) I'll be lucky to get a decent obsfucation of 5 lines the way its going...LOL

    Cya,
    Clandestiny

  9. #24
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,146
    Blog Entries
    5
    Hi Clandestiny,

    Quiet in here isn't it? Just the sound of our own voices echoing off the walls...

    You're right, that was *very* optimized and basic SMC. I had used 6 nops as the 'reserved' bytes where the new SMC generated jump was to be created just for clarity. If I had used real code totalling 6 bytes, then in the case of a Short jump, which is only 2 bytes long, there would be 4 bytes left over which as you say, could translate into bogus code which would screw up the rest of the code below. It didn't really matter anyway because the Short jump jumped over any bad code directly to the proper address in any case.

    I know what you mean by generating a block of SMC is more challenging. And confusing. I was thinking you could always pad extra bytes with nops or some other innocuous series of bytes to make it easier. Say you wanted to create an 8 byte code sequence. You could have a bogus 5 byte Call statement, say to GetTickCount or some other API which doesn't push anything onto the stack, or maybe to a fake call somewhere in your code. Then pretend to mov the return value to some garbage variable, producing another 5 bytes to play with

    E82C5AB7BF CALL KERNEL32!GetTickCount
    A334124000 MOV [00401234],EAX

    This now looks like valid confuse-a-cracker code Then your SMC generating code can mov 2 DWORDS worth of bytes giving you the new 8 byte code sequence, and a WORD mov of 9090 will fix up the extra 2 bytes so it doesn't crash. Or you could use inc eax, dec eax or something like that.

    Again though, even this is very simplistic. You probably don't want all these extra nops kicking around but would prefer the SMC and original code to "mesh".

    I suppose you could even have "layers" of SMC - a mov dword statement *creating* another mov dword statement which produces the real SMC code you want. Yikes, the brain reels at the House of Mirrors concept.

    Hey Clandestiny, I know you're a talented graphic artist, I've seen some of your work. I know you like to take a word or idea and conceptualize it into an image. Think you could do that with the programming concept of SMC? Y'know, the Board *could* use a fancy graphic to jazz it up a bit... ^_^

    ...seed planted...

    ...water...

    ...feed...

    ...weed...

    ...Blossom!

    Cheers,
    Kayaker

  10. #25
    smokin'
    Guest

    link

    I can't get the link to harlequin home page to work. Does anyone know if he moved or what?

    Sorry all, couldn't get it to work for 2days but it's working again to night!
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  11. #26
    Cold Coder
    Guest
    Hi all

    http://www.angelcities.com/members/harlequin/
    http://www.Harlequin00.cjb.net
    http://htasks.cjb.net/fx23ht.zip

    all work for me
    --------------
    This how i did the SMC for fx23ht.exe
    ; at about 004010CA and WellDone at NA(not telling hehehe)
    mov eax, Modif
    mov dword ptr [eax], 0Fh*1h + 84h*100h + (WellDone-Modif-6)*10000h
    Modif EQU $
    ;C7h, 00h_________, 0Fh, 84h, 00h, 00h
    mov dword ptr [eax], 0000840Fh ; give us 6 bytes(for jz xxxx0000)

    2 other things
    here some thing cool
    :00401142 80F3DC xor bl, DC ; aka '‹' aka ALT 666(you bad Harlequins)

    and fx23ht.exe has a cool bug at about WellDone by sending hInstance and not hWnd to MessageBox get it into a loop(well for me it dos)

    Cheers,
    Cold Coder
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  12. #27
    Cold Coder
    Guest
    Hi smokin,
    one more thing harlequin is away right now(i think he will b back soon) so if it go down 100% then it down for now.

    cya,
    Cold Coder
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  13. #28
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,146
    Blog Entries
    5
    Hi Cold Coder,

    Glad to see someone else working on this. You're right, hInstance is pushed as the 1st param in the MessageBox calls rather that hWnd, which is what it's supposed to be (or NULL) according to the API reference, even though it doesn't seem to make a great deal of difference. I hadn't noticed this error, just recognized 400000 in Harl's original file as an Instance handle returned from the GetModuleHandleA call, and used hInstance in my code. Unfortunately this doesn't get rid of the infernal message loop when you get the correct 'serial', at least for me.

    If I use hInstance or NULL as the 1st param of the MessageBox call, I get multiple message boxes and a flickering of the dialog window. If I use hWnd, I get multiple message boxes, but the flickering stops and it seems to exit from the loop a bit more gracefully.

    It still seems to have to do with wm_command being processed too many times. If you set a bp on the code line .ELSEIF uMsg==WM_COMMAND (401044 in the original file), and step over the good MessageBox when it's called, you immediately break at that wm_command line again, even before the MessageBox call finishes and displays its message. So of course the GetWindowTextA / cmp dword ptr [variable], 73704F4Fh / MessageBox routine gets called *again*, which is totally redundant.

    wm_command is also sent when a control sends a notification message to its parent window. I used Winsight to monitor the windows messages in both the main dialog and the edit control when something is typed into the edit box. After the 1st wm_command is processed, it seems there are still some messages from the edit box sitting in the message queue , one (or more) of them which cause further wm_command messages to be sent to the main window, causing the bug.

    I haven't tracked down the exact source of the multiple wm_command messages. I think this is just a one-off problem with using wm_command as a tricky way to monitor when there's a change in the edit box. Maybe using a less generic wm_ message such as WM_GETTEXT or WM_GETDLGCODE (both of which are also sent by the edit box) might work better.

    Cheers,
    Kayaker

  14. #29
    Cold Coder
    Guest
    Hi Kayaker,

    > Glad to see someone else working on this.
    I have bin here/working(i think some other ppl have too "read 435 times") from the start project.(i just think my post sucks so i do not post much)

    This what i did i used the edit box hWnd as it save any way(bing the way code work i have to save the main one). So this may have stop all message from the Edit box.

    Cheers,
    Cold Coder
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  15. #30
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,146
    Blog Entries
    5
    Hi All,

    I came up with a solution to the errant message loop problem in Harlequin's original file that caused that flickering/mulitiple message boxes. The wm_command processing loop needed another test to isolate when a single change was occuring in the edit box before continuing on to the GetWindowTextA call.

    If you use Winsight (or Ispy) to monitor the wm_command windows messages being sent to the dialog box when you type a character into the edit box, you also get the values of wParam and lParam. For each keystroke entered there are 2 wm_command (111h) messages sent from the child window (the edit box) to the parent window (the dialog box):

    "Harlequin 7" WM_0x111 Sent wp=0400006B lp=00000524
    "Harlequin 7" WM_0x111 Sent wp=0300006B lp=00000524

    lParam just gives the hWnd of the child window
    The low-order word of wParam is the Control ID = 006B = the edit box ID
    The high-order word of wParam is the Notification Code

    The Notification Code is the interesting one. There are 2 of them, 0400 and 0300. Doing a search for them I found they corresponded to EN_UPDATE and EN_CHANGE.

    The EN_UPDATE notification message is sent when an edit control is about to display altered text. This notification message is sent after the control has formatted the text, but before it displays the text. This makes it possible to resize the edit control window, if necessary. The parent window of the edit control receives this notification message through the WM_COMMAND message.

    The EN_CHANGE notification message is sent when the user has taken an action that may have altered text in an edit control. Unlike the EN_UPDATE notification message, this notification message is sent after Windows updates the screen. The parent window of the edit control receives this notification message through the WM_COMMAND message.


    So now either one of these messages can be used to make sure the GetWindowTextA routine is called only once for each keystroke:
    ------------------------------------------
    .ELSEIF uMsg==WM_COMMAND
    jmp wmcommand
    .
    .

    wmcommand:
    mov eax,wParam ; check low-order word of wParam
    .IF ax==IDC_BUTTON ; button pushed?
    invoke FakeCheck,hWnd

    .ELSEIF ax==IDC_EDIT ; something entered into edit box (ID=6B)?
    shr eax,16 ; shr to check high-order word of wParam
    .if ax==EN_CHANGE ; equal to 0300?

    invoke GetWindowTextA, hEditReg, ADDR strReg, 20h
    cmp dword ptr [strReg], 73704F4Fh
    .
    .
    ------------------------------------------------

    I also set a BMSG hwnd WM_COMMAND breakpoint in SoftIce to monitor things and found something unusual. SI lists the Notification Code in lParam instead of wParam. This must just be an internal syntax because according to all API documentation, Numega's got it wrong!

    Break due to BMSG 0B34 WM_COMMAND
    hWnd=0B34 wParam=006B lParam=03000B3C msg=0111 WM_COMMAND

    Just thought this might be interesting. At least now I can sleep better

    Kayaker

Similar Threads

  1. RDP Botnets : Malware Google Dorking - Not an Easy Task
    By OpenRCE_adityaks in forum Blogs Forum
    Replies: 0
    Last Post: December 4th, 2007, 13:00
  2. My Challenge To You
    By KSR0x2b in forum Mini Project Area
    Replies: 25
    Last Post: February 21st, 2002, 22:33
  3. Rsa Challenge
    By int21hex in forum RCE Cryptographics
    Replies: 10
    Last Post: January 29th, 2002, 12:07
  4. Help! Task & Ldt & Hwnd?!
    By dzhiguo in forum Malware Analysis and Unpacking Forum
    Replies: 1
    Last Post: August 28th, 2001, 05:15
  5. Task 4 CRC hints
    By Kayaker in forum Mini Project Area
    Replies: 2
    Last Post: November 30th, 2000, 00:31

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •