Page 3 of 3 FirstFirst 123
Results 31 to 42 of 42

Thread: dongle app written in dos

  1. #31
    reknihT esreveR SiGiNT's Avatar
    Join Date
    Sep 2004
    Location
    Wherever I am
    Posts
    750
    ALT - PrintScreen also works.

    SiGiNT

    Just a thought but would DLDR.EXE >PRN work?
    Last edited by SiGiNT; February 2nd, 2006 at 19:36.
    Unemployed old fart Geek - Self Employed Annoyance
    Team: Noobisco Crackers
    If someone can't do it for you, you'll never learn!

  2. #32
    ksbrace
    Guest
    Ok, I stepped through both machines at the same time to try and figure out where the paths are different. At this point I need to turn to someone for some advice. Both take the same path up until this loop:
    Code:
    * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
    |:0001.0359(C), :0001.0362(C)
    |
    :0001.034B F2                     repnz
    :0001.034C AE                     scasb
    :0001.034D E31F                   jcxz 036E
    :0001.034F 263A05                 cmp al , es:[di]
    :0001.0352 741A                   je 036E
    :0001.0354 26813D3837             cmp word ptr es:[di], 3738
    :0001.0359 75F0                   jne 034B
    :0001.035B 268B5502               mov dx, es:[di+02]
    :0001.035F 80FA3D                 cmp dl, 3D
    :0001.0362 75E7                   jne 034B
    :0001.0364 43                     inc bx
    :0001.0365 80E6DF                 and dh, DF
    :0001.0368 80FE59                 cmp dh, 59
    :0001.036B 7501                   jne 036E
    :0001.036D 43                     inc bx
    at .0352 the good one, doesn't jump until much later than the bad one does. I'm not sure what I should be looking for to compare the two. Thanks in advance.
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  3. #33
    reknihT esreveR SiGiNT's Avatar
    Join Date
    Sep 2004
    Location
    Wherever I am
    Posts
    750
    Well, I haven't been following this very closely, but it looks to me like you've found the dongle reading routine - if they both jump at .0352, then my guess is your "good guy" "bad guy" jump is somewhere after that jump.

    SiGiNT
    Unemployed old fart Geek - Self Employed Annoyance
    Team: Noobisco Crackers
    If someone can't do it for you, you'll never learn!

  4. #34
    Quote Originally Posted by ksbrace
    Ok, I stepped through both machines at the same time to try and figure out where the paths are different. At this point I need to turn to someone for some advice. Both take the same path up until this loop:
    Code:
    :0001.034B F2                     repnz
    :0001.034C AE                     scasb
    :0001.034D E31F                   jcxz 036E
    :0001.034F 263A05                 cmp al , es:[di]
    :0001.0352 741A                   je 036E
    :0001.0354 26813D3837             cmp word ptr es:[di], 3738
    :0001.0359 75F0                   jne 034B
    :0001.035B 268B5502               mov dx, es:[di+02]
    :0001.035F 80FA3D                 cmp dl, 3D
    :0001.0362 75E7                   jne 034B
    :0001.0364 43                     inc bx
    :0001.0365 80E6DF                 and dh, DF
    :0001.0368 80FE59                 cmp dh, 59
    :0001.036B 7501                   jne 036E
    :0001.036D 43                     inc bx
    at .0352 the good one, doesn't jump until much later than the bad one does. I'm not sure what I should be looking for to compare the two. Thanks in advance.
    You're looking in the wrong place. That would be the environment block parser of Borland's Turbo-C and C++ startup code

    The annotated source I have of the startup module (v.2.01) matches almost exactly (it's slightly different because of the different version...):
    Code:
        les     di [.env]    ; point to env block
        mov     ax di
        mov     bx ax
        mov     cx h7FFF      ; look thru max 32767 bytes
    :Check_87
        es
        cmp     w[di] '78'    ; we have envar "87"?
        jnz     .No_87
        es
        mov     dx [di+2]
        cmp     dl h3D    ; '=' - "87=" ?
        jne     .No_87
        and     dh hDF    ; conv upcase
        inc     w[.use_8087]
        cmp     dh 'Y'    ; "87=Y" ?
        jne     .No_87    ; no...
        inc     w[.use_8087]
    :No_87
        repnz scasb
        jcxz    .No_more_env      ; dont try to go past 32k of env
        inc     bx              ; one more env var to check...
        es
        cmp     [di] al    ; end?
        jnz     .Check_87    ; no, keep going...
    If you're interested in the rest of the startup code, Google "c0.asm" (w/o the quotes) and it'll be the first link.

    The *real* start of your program's code can be found by locating the call to the main() function, which looks like this:
    Code:
        push [.env]
        push [.argv]
        push [.argc]
        call .main
    Those three pushes are distinctive and easy to find. Look for an Int 1A and it'll be a few instructions down. Start your analysis at the main() function.
    Last edited by LLXX; February 4th, 2006 at 02:41.

  5. #35
    ksbrace
    Guest
    As I step through both machines, I come to .5F89. Here, I'm seeing some bizarre behaviors and I'm not sure if this is a place that I care about or not.
    On the Good machine, sometimes it jumps and sometimes it doesn't. Same with the Bad machine.
    I ran it about 6 times through this area to try and compare because the first time through they were different:
    Good Guy
    5f89 jumps to 5f99
    5fa0 jumps to 5f84
    5f89 no jump
    5f97 jumps to 5fa2
    returns to 0214
    ---
    Good Guy:
    5f89 no jump
    5f97 jumps to 5fa2
    returns to 0214
    ---

    Bad Guy:
    5f89 jumps to 5f99
    5fa0 jumps to 5f84
    5f89 jumps to 5f99
    5fa0 jumps to 5f84
    5f89 jumps to 5f99
    5fa0 jumps to 5f84
    5f89 no jump
    5f97 jumps to 5fa2
    returns to 0214
    ---
    Bad Guy:
    5f89 no jump
    5f97 jumps to 5fa2
    returns to 0214

    Am I wasting mine/your time looking in this area? Thanks in advance!


    [/code]
    :0001.5F70 C3 ret

    :0001.5F71 55 push bp
    :0001.5F72 8BEC mov bp, sp
    :0001.5F74 83EC02 sub sp, 0002
    :0001.5F77 56 push si
    :0001.5F78 57 push di
    :0001.5F79 1E push ds
    :0001.5F7A B8F23D mov ax, 3DF2
    :0001.5F7D 8ED8 mov ds, ax
    :0001.5F7F C746FE0000 mov word ptr [bp-02], 0000

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:0001.5FA0(C)
    |
    :0001.5F84 E8C5FF call 5F4C
    :0001.5F87 A801 test al, 01
    :0001.5F89 750E jne 5F99
    :0001.5F8B C706AC0C0000 mov word ptr [0CAC], 0000
    :0001.5F91 C706AA0CA904 mov word ptr [0CAA], 04A9
    :0001.5F97 EB09 jmp 5FA2



    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:0001.5F89(C)
    |
    :0001.5F99 FF46FE inc word ptr [bp-02]
    :0001.5F9C 837EFE64 cmp word ptr [bp-02], 0064
    :0001.5FA0 7CE2 jl 5F84

    * Referenced by a (U)nconditional or (C)onditional Jump at Address:
    |:0001.5F97(U)
    |
    :0001.5FA2 1F pop ds
    :0001.5FA3 5F pop di
    :0001.5FA4 5E pop si
    :0001.5FA5 8BE5 mov sp, bp
    :0001.5FA7 5D pop bp
    :0001.5FA8 CB retf
    [/code]

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

    LLXX,
    Now, when I try to analyze the main function, by setting breakpoint at .0F3F or any of the below addresses, it never stops, Good Guy or Bad Guy.

    Code:
    :0001.0F3E CB                     retf
    
    
    :0001.0F3F 55                     push bp
    :0001.0F40 8BEC                   mov bp, sp
    :0001.0F42 56                     push si
    :0001.0F43 57                     push di
    :0001.0F44 8A6606                 mov ah, [bp+06]
    :0001.0F47 8B4E0A                 mov cx, [bp+0A]
    :0001.0F4A 8B5608                 mov dx, [bp+08]
    :0001.0F4D CD1A                   int 1A
    :0001.0F4F 92                     xchg ax,dx
    :0001.0F50 8BD1                   mov dx, cx
    :0001.0F52 5F                     pop di
    :0001.0F53 5E                     pop si
    :0001.0F54 5D                     pop bp
    :0001.0F55 CB                     retf
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  6. #36
    The 5Fxx code seems to be calling 5F4C until it either returns 0 or has been called 100 times, whichever comes first. The "success" path would set [0CAC] to 0000 and [0CAA] to 04A9 (1193? do you recognise this number?) and then return, otherwise 0CAA and 0CAC are left unchanged. Here's a diagram of the flow:
    Code:
    ...start...
    5F84 E8C5FF call 5F4C <-----------------------+
    5F87 A801 test al, 01                         |
    5F89 750E jne 5F99 >------------------------+ |
    5F8B C706AC0C0000 mov word ptr [0CAC], 0000 | |
    5F91 C706AA0CA904 mov word ptr [0CAA], 04A9 | |
    5F97 EB09 jmp 5FA2 >---------------------+  | |
    5F99 FF46FE inc word ptr [bp-02] <-------|--+ |
    5F9C 837EFE64 cmp word ptr [bp-02], 0064 |    |
    5FA0 7CE2 jl 5F84 >----------------------|----+
    5FA2 1F pop ds <-------------------------+
    ...return...
    You should look inside 5F4C to see if there's anything interesting there, as the above loop is rather generic and isn't something that is specifically associated with d0ngles.

    You've found the wrong Int 1A - look at the code and think! Would the call to main() be located inside a function that simply interfaces to Int1A? Once again, think! What you have there is a function! See the push bp | mov bp sp ? You should know that that is the standard opening sequence of a function, and that retf ends it!

    Start at the real entrypoint and follow the code flow. You should travel through the environment parser I described earlier, followed by some calculations and Int 21 calls to setup the memory, a rep stosb or rep stosw to initialise the Bullshit Segment (BSS), then a few calls, an int 1A and then the series of Pushes followed by the call to main() itself. If you can't locate those items in your program, you need to spend some more time studying the code and looking at it from a higher perspective. The fact that what you thought was the protection check was in fact the environment block parser indicates that you should definitely take some time to study more Asm and understand the functioning of the program on the large scale, not just line-by-line.

  7. #37
    nchanta
    Guest
    If it is indeed sentinal, it may be a good idea to search for the common sentinal constant 0x07242, if you haven't already.

    Oh, and read up about sentinal at woodman.com/crackz
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  8. #38
    Who knows what it is... anyway I cracked his target already by forcing one and killing another conditional jump.

  9. #39
    ksbrace
    Guest
    Here is the pm from LLXX on how the target was cracked:

    Hello,

    Sorry to disappoint you, but the protection was much easier than I expected. I didn't even need to use IDA, and later when I loaded it into IDA it didn't disassemble very well, maybe that is where your difficulty exists. Always try easy way first! Target_1.exe checks once and was cracked in approximately 20 seconds, Target_2.exe checked twice and took 1 minute of my time

    I'll explain now how I did it. First of all, get the general feeling of the target. Load into a text editor and look around. You find "Borland" string in there, this means it was compiled with Borland's C/C++ runtime library - important information to know, so you don't spend time tracing through the startup code like you did. Run the program. Target_1.exe first, gives the message that security is missing etc. Then, just use DOS debugger DEBUG.EXE to inspect. Run it from cmd prompt like:

    debug Target_1.exe

    You see the "-" which is prompt of action. You can type ? and press Enter to get the list of commands. First of all, since we know that Borland startup code is linked, the task is to find where main() function is. Enter u and press Enter to see the entrypoint. You should see the "mov ah 30" "int 21" which is very typical for startup code to do, it is just checking for DOS version. I did u 10 more times, and at :0122 finds INT 1A which you said couldn't find? This means the assumption is correct, indeed we are in the startup code. U once more, and see:

    Code:

    0143 BE9C2E MOV SI,2E9C

    0146 BFC02E MOV DI,2EC0

    0149 E8D000 CALL 021C

    014C FF368800 PUSH [0088]

    0150 FF368600 PUSH [0086]

    0154 FF368400 PUSH [0084]

    0158 E8D631 CALL 3331Recognise these pushes? It is very important! This is call to main() we have found. main() is at 3331, so run till 3331 with command g 3331 (go until 3331). Now you see the Registers displayed and push bp at the location 3331, this is the start of main(). This now takes to pay more attention to the detail, start stepping through the program. Use command p to step through without entering the CALLs. After p'ing 29 times hits Welcome screen. Press any key to exit the welcome screen, and stops at the CALL 51B3. P again, the screen clears and sees CALL 19BB. P again. See the error message comes up! Press ESC to terminate for now, 19BB returns and sees the OR AX, AX stopped at. Step once, then finds "JNZ 33A0" - now think, why would conditional jump be present after check of d0ngle? 19BB returns AX = 0, so that means FAILURE, so in this case it should not be zero, we forces it to jump by places command e cs:3396 eb which inserts EB byte (JMP opcode) into the cs:3396 where JNZ originally was. Nothing will display when you run this command, but use r command to show the current state, and finds JMP 33A0 has been shown, the byte indicates has changed from 7508 to EB08. Thinks we have found the critical jump, run g command to continue with the execution. It works! Continue entering the data, etc. Now finishes "Billing Summary" screen, press ESC and it will exit back to DEBUG, shows message "Program terminated normally" and the prompt. Run command q to exit. One supplementary exercise: It contains the year 2000 bug with the entered date. Figure out how to fix that

    It actually takes much less time to step through and find the jump than to describe it above... you try it yourself and see how quick it was. Now, onto Target_2.exe - unfortunately PM system won't let me send more than 3.9Kb at once, see the next message...

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

    Opens the executable in the editor, look around. It is compiled with same Borland compiler, it seems. Also note the size: 326Kb. This is much larger than the other one, so have to watch out for the segmentation when inspecting the code. Run the file. See "security error" message. It seems to be the first output produced, so the security error must be closer to the start than in the other one.

    Load it into debug. Again, u. You'll see almost the same sequence of instructions as in the other one, this is a good sign that the compiler is the same. Keep u, but this time sees not the INT 1A after 9 u's, but already the pushes. Perhaps this is what confused you, however you must think - it is slightly different but you see the very easy recognises

    Code:

    0115 FF367200 PUSH [0072]

    0119 FF367000 PUSH [0070]

    011D FF366E00 PUSH [006E]

    0121 FF366C00 PUSH [006C]and you know that INT 1A was executed, so then where is it? You found in the disassembly that INT 1A, and I told you it was part of a function, so that function must've been called before that. Did you notice all the CALLs that took place before the PUSHs? It most likely was one of them. U again, and finds the:

    Code:

    0125 FF366A00 PUSH [006A]

    0129 9AE390501D CALL 1D50:90E3That is definitely the main() function (it might not be at segment 1D50, but the offset 90E3 will be the same on your machine). However, notice that the call is different from the one in the other program. Also notice that this program is much larger than the other program. This is known as an intersegment or far call, i.e. the location of call is in another segment. Then, instead of g 3331 earlier, run command g 1d50:90e3 (substitute whatever segment your program is, since I don't think it's going to be 1d50 as well). Arrives the position:

    Code:

    AX=0100 BX=0EEA CX=0FB4 DX=0EEA SP=0FD2 BP=0FE4 SI=0EA8 DI=0EEA

    DS=50C2 ES=50C2 SS=51B3 CS=1D50 IP=90E3 NV UP EI PL ZR NA PE NC

    1D50:90E3 55 PUSH BPSees again that we have reached main() entrypoint.

    Again 4000 byte PM limit... see part 3...

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

    As with the other one, repeat p command until find something interesting. In this case, I had to do it 118 times - watch for this:

    Code:

    AX=6914 BX=004C CX=0000 DX=71D8 SP=0F5E BP=0FD0 SI=0EA8 DI=0EEA

    DS=4640 ES=71D8 SS=51B3 CS=1D50 IP=92D9 NV UP EI PL NZ AC PO NC

    1D50:92D9 9ABD43EB3B CALL 3BEB:43BDAgain, the segments will be different, but notice the CALL - the code is in segment 1d50, but it's calling far away to 3beb. When runs the command p I notice a slight pause before it returns. This is different from all the previous p's, so something interesting is happening. It might be trying to access the dongle. Pay more attention now. P two more times over the POP CX's, then notice AX = FFFF when find the instruction MOV SI, AX. P again, and find CMP AX, FFFF and then P over that, find JZ 92AC. This is important. From use of logic, think that if the CALL succeeded, it would not return FFFF (-1) which normally indicates ERROR. So, this should not jump, and it should be striked out with two NOPs. Use the command e cs:92e5 90 90 just like the previous program to strike out the JZ, and then r to see that it has been changed to NOP. Also, use u to see what the upcoming code is going to be. You'll see more far CALLs to 43bd, i.e. what seems to be the dongle code. That means that the protection check isn't over yet (if you try to run right now, only after killing the first jmp, you get "Security error #3"). P over these, until you get to the MOV SI, AX followed by CMP SI, -01. Notice once again, AX is FFFF without the dongle. Following the CMP SI, -01 (-01 is equal to FFFF), at 9314, is JNZ 9329. Following the logic, if AX was not FFFF, i.e. the dongle is OK, it will jump to 9329. Instead of killing this jump with NOP, we have to force it. The command is e cs:9314 eb. Once again, r to confirm that it has changed to JMP 9329, then P over it and U to see the upcoming code. No more calls to 43bd, it seems. We can try to run it now, with g. It works (as far as I can tell...). Again, the description I wrote above makes it seem more difficult than it really is. Try it

    IMHO, this prog wasn't really worth cracking for use, but as an educational experience, it's nice. Surprisingly easy to crack for a "dongle", and I haven't the dongle either. On a difficulty scale of 0 - F, Target_1.exe would be 0 and Target_2.exe maybe 0.5 at the most. This program reminds me of an exercise I had in a programming class once...

    Try the crackme in the project area if you want something more interesting to crackg
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  10. #40
    ksbrace
    Guest
    Ok, I was reviewing everything and looking at the 2nd target in hiew and came up with the following question:
    What would be the difference of changing a 74C5 to 75C5 as opposed to nop'ng out the 74C5. LLXX, had nop'd out this jump. I went back and changed it to 75C5 from the nops and it still appears to be working correctly. So, I'm just looking for clarification if both are acceptable or the nop is preferred, etc... I posted a small tidbit of the code below:
    Code:
    * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
    |:0002.3AAA(U), :0002.3ACC(C)
    |
    :0002.3AD4 1E                     push ds
    :0002.3AD5 B81469                 mov ax, 6914
    :0002.3AD8 50                     push ax
    :0002.3AD9 9ABD431B29             call 291B:43BD
    :0002.3ADE 59                     pop cx
    :0002.3ADF 59                     pop cx
    :0002.3AE0 8BF0                   mov si, ax
    :0002.3AE2 3DFFFF                 cmp ax, FFFF
    :0002.3AE5 74C5                   je 3AAC
    :0002.3AE7 1E                     push ds
    :0002.3AE8 B85D69                 mov ax, 695D
    :0002.3AEB 50                     push ax
    :0002.3AEC 9ABD431B29             call 291B:43BD
    :0002.3AF1 59                     pop cx
    :0002.3AF2 59                     pop cx
    :0002.3AF3 8BF0                   mov si, ax
    :0002.3AF5 1E                     push ds
    :0002.3AF6 B87069                 mov ax, 6970
    :0002.3AF9 50                     push ax
    :0002.3AFA 9ABD431B29             call 291B:43BD
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  11. #41
    reknihT esreveR SiGiNT's Avatar
    Join Date
    Sep 2004
    Location
    Wherever I am
    Posts
    750
    The only difference is if you nop it then there is no chance that the jump will be taken, same with changing a JNE to JMP if you want it to jump or nop if you don't - either is acceptable but from what I've seen nopping and hard jmps are the preferred method.

    SiGiNT
    Unemployed old fart Geek - Self Employed Annoyance
    Team: Noobisco Crackers
    If someone can't do it for you, you'll never learn!

  12. #42
    Inverting jumps will invert the behavior, of course. What was once a target that loved the dongle will now detest it, and refuse to run *with* the dongle. If you find this situation of a program that hates dongles interesting and slightly humorous, then go ahead. Otherwise, forcing the logic is the best way, as it is now indifferent to the presence or absence of the dongle.

Similar Threads

  1. Replies: 1
    Last Post: November 15th, 2013, 23:38
  2. Replies: 1
    Last Post: August 31st, 2005, 23:06
  3. Assembly incorrect for the written code
    By yaa in forum OllyDbg Support Forums
    Replies: 1
    Last Post: January 9th, 2004, 12:08
  4. +puark's never written articles
    By yaa in forum The Newbie Forum
    Replies: 0
    Last Post: December 8th, 2002, 01:29
  5. how do i use SICE to do what i want to do with programs written in VB
    By yobo in forum Malware Analysis and Unpacking Forum
    Replies: 1
    Last Post: April 26th, 2001, 14:37

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
  •