Page 1 of 2 12 LastLast
Results 1 to 15 of 19

Thread: Serial fishing

  1. #1

    Serial fishing

    Trying to get a bit if rust out and need some current advice on serial fishing, such as likely techniques of the day. I am still stuck in the day of hmemcpy and setting a BP in softice on dialog in serial entry box.

    This app uses a TLS callback for sure and it does various time checks before the entry point. I managed to make progress using getwindowtextA and got to a routine checking my bogus entry with two magic numbers, featuring addition and XORs. I am guessing they have taken the legitimate serial and obfuscated it using boolean logic but I am stymied by a couple of points.

    1)they check against 0xA and 0xD, the old linefeed/carriage return combo. There is room in the serial entry box to write a small novel so I am assuming the length of the number is greater than the width of the box, requiring a linefeed/CR. Then again, one should never assume anything.

    2)if that is true, then I presume there should be checks for dashes, delineating sets of numbers as well.

    Any ideas?

    3)wrt to the TLS callback, has anyone simply zeroed the entry in the PE header. I can see all sorts of problems with that if their are further callbacks written into the app.

  2. #2
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,114
    Blog Entries
    5
    Don't really know how to answer that. If the TLS callback is being used for benign purposes (i.e. to "call constructors and destructors for objects" as the PECOFF file suggests a use for), then ignore it. If it's malicious (read anti-debug), then you might as well be full-on paranoid and assume the timing checks are for anti-tracing, it dynamically modifies code, and it's already detected that it's under a debugger and the serial routine you're chasing is a bogus "fool-the-cracker" routine. How's that for old school?

    You might as well figure out what the TLS callback is doing first, just so you know what the score is.

    As for the rest, you might also try it in reverse. You've likely done this before, rather than approaching the core algorithm from the serial entry box route, use ProcessMonitor to see if you can find it searching for a registry entry or license file when validly registered. Fake as required to get further along to the algo. You may end up in the exact same code, but it's also possible it may clarify some things, like whether the 0x0A0D or spaces/dashes are relevant.

  3. #3
    Quote Originally Posted by Kayaker View Post
    You might as well figure out what the TLS callback is doing first, just so you know what the score is.
    I spent some time with the TLS code but I am presuming that's what it is. There is a TLS entry that CFF explorer lists with address of callbacks and an index, but I am not quite sure where I should be looking.

    Anyway, when it loads in softice, you get the typical Invalid schtick till you do a single step, so I missed out initially on the first program step. After tracing through the entry code and doing a ret, I can see that the first program step is a call to the routine I mentioned. I am not too clear whether the system called that address and softice picked it up as the TLS unfolded, but the address of the call is not the address listed as the entry point by PE header analysis software. The EP is jumped to immediately after this routine.

    The routine is plain weird...at least to me. It calls time functions and queryperformancecounter but it's what it does with the returned values that is weird. To begin with, it puts a double word in eax from a particular data address. A few steps later, it produces the same number as a magic, hard-coded into the code, and moves it to edi. Then it compares them by comparing eax to edi. I'll call the data memory location that had the magic number stored, xxxxxxxx, because it shows up later.

    Here's where the weirdness begins. It calls GetSystenTimeAsFileTime, which returns values in eax and edx. These values are also at ebp-4 and ebp-8, for some reason (doh!! the ebp values were passed to the func as an esp value). It moves one of them to esi, then it xor's them together and the result is in esi. Just to get that straight, it has xored the MSB and the LSB values of the time returned from the time function. So, esi now has that xored value.

    Now it calls GetCurrentProcessId and gets a value...32c. I checked that it is the proc id of my app and it is. It now xor's the pid with esi. Then it calls GetCurrentThreadId, which is d6c, and xor's esi with that. To summarize, it has gotten system time, xored the msb and lsb, called for the proc and thread ids, and xored the xored time values with each of those values.

    Don't go away, it gets better. It now calls GetTickCount and xor's esi with the msb stored in eax of the returned value. It discards the lsb value from edx. Now it calls QueryPerformanceCounter but it switches things up a bit. It moves a value from the stack into eax which is 0. Then it xors 0 with a value retrieved from QPF, then it xors that value in eax with esi. Then it compares esi with eax and, of course, they are not equal.

    So it jumps. Had they been equal, it would have moved the original magic number into esi (as a hard-coded value from the code) then back to the original data memory location I earlier labeled xxxxxxxx. Then it would 'not' that value (invert it) and store the inverse at the next highest data memory location.

    Meanwhile, back at the ranch, we have just done a jump because esi and eax were not equal, after having xored them. Now it tests esi with a value in ebx that was ffff0000. It tests them and they are not equal, so it jumps again.

    The place it jumps to is the same location I just mentioned where the magic number is moved to esi then into data memory location xxxxxxxxx. Of course, esi is not the same as the magic, but it is notted as well and the inverse is stored at the next highest data memory location to xxxxxxxx. It seems the app has provided a magic number and stored it at xxxxxxxx, and under certain conditions it puts it back there, and under other conditions it stores the xored time values with the pid and tid at xxxxxxxx. It might be an idea to put a bpx on that location and let the app run.

    I have probably now lost you completely. I could post this section of code but I don't know if that is still kosher. I should mention that if the last jump had not been made, because esi and eax were equal, esi would have been moved to eax. Then it would have gotten an shl 10, then ored with the original esi.

    I know this sounds hopelessly convoluted, but I am trying to think why they would want to do all this. We know that the thread and proc id's will change each time the app is rebooted. I was thinking they might be using this as a way to verify the serial, but not if they use a random variable like the pid and tid. It has also occured to me that they can tell by the way the values change whether or not it is being single-stepped, or even halted at a bpx.

    Maybe they can use it to check for single-stepping but I don't see how they could specifically check for a debugger using just that info.

    Once this routine finishes, it returns to a jmp that directs it into heap initialization to begin the thread proper. Next up is GetVersion, etc., then a bit further there is a call to winmain.

  4. #4
    Super Moderator
    Join Date
    Dec 2004
    Posts
    1,508
    Blog Entries
    15
    sorry i didnt read your post entirely and i need to get off this damn net and do some work
    but from what i glanced i assume you are single stepping through the standard WinMainCrt() entry

    ps
    don't scream at me "Am I a noob dont i know what crtmain is " if i had i assumed wrong

  5. #5
    Quote Originally Posted by blabberer View Post
    ... i assume you are single stepping through the standard WinMainCrt()
    If by WinMainCrt() you are refering to the code between the app entry point and the call to winmain(), yes. In either Olly or softice, I am beginning from the very first code instruction called from kernel32. I am not talking about the windows code itself, rather the initialization code that happens before winmain is called.

    It's not clear to me how a TLS Callback would appear in Olly/softice. If code was called before the thread code was officially executed, would it show up in olly/softice as code addresses listed under the apps name, coming before the official app entry point?

    Even at that, this is peculiar stuff because the very first instruction is to a call with the time-related functions in it. This happens before the heap is created or any other stuff like GetVersion, GetCommandLine, whatever.

    Kayaker suggested it could be related to constructors/destructors but why the magic numbers and the xoring using retrieved time, pid's and tid's?

  6. #6
    Super Moderator
    Join Date
    Dec 2004
    Posts
    1,508
    Blog Entries
    15
    sorry for replying to my own post
    but i cant get rid of this addiction

    yes you are talking about a routine that is plain standard
    it either has BufferOverflows.h included or is compiled with wdk
    so GsCookie is being initialised in that routine (to catch stack based overflow exploits)

    doesnt ida recognize this and collapse this ??

    does it look like this

    Code:
    01002EC1 >MOV     EDI, EDI
    01002EC3  PUSH    EBP
    01002EC4  MOV     EBP, ESP
    01002EC6  SUB     ESP, 10
    01002EC9  MOV     EAX, DWORD PTR DS:[__security_cookie]
    01002ECE  AND     DWORD PTR SS:[EBP-8], 0  //dwlow
    01002ED2  AND     DWORD PTR SS:[EBP-4], 0 // dwhigh
    01002ED6  PUSH    EBX
    01002ED7  PUSH    EDI
    01002ED8  MOV     EDI, BB40E64E
    01002EDD  MOV     EBX, FFFF0000
    01002EE2  CMP     EAX, EDI
    01002EE4  JE      SHORT 01002EF3
    01002EE6  TEST    EBX, EAX
    01002EE8  JE      SHORT 01002EF3
    01002EEA  NOT     EAX
    01002EEC  MOV     DWORD PTR DS:[__security_cookie_complement], EAX
    01002EF1  JMP     SHORT 01002F4E
    01002EF3  PUSH    ESI
    01002EF4  LEA     EAX, DWORD PTR SS:[EBP-8]
    01002EF7  PUSH    EAX
    01002EF8  CALL    NEAR DWORD PTR DS:[<&KERNEL32.GetSystemTimeAsFileTime>]
    01002EFE  MOV     ESI, DWORD PTR SS:[EBP-4]
    01002F01  XOR     ESI, DWORD PTR SS:[EBP-8]
    01002F04  CALL    NEAR DWORD PTR DS:[<&KERNEL32.GetCurrentProcessId>]
    01002F0A  XOR     ESI, EAX
    01002F0C  CALL    NEAR DWORD PTR DS:[<&KERNEL32.GetCurrentThreadId>]
    01002F12  XOR     ESI, EAX
    01002F14  CALL    NEAR DWORD PTR DS:[<&KERNEL32.GetTickCount>]
    01002F1A  XOR     ESI, EAX
    01002F1C  LEA     EAX, DWORD PTR SS:[EBP-10]
    01002F1F  PUSH    EAX
    01002F20  CALL    NEAR DWORD PTR DS:[<&KERNEL32.QueryPerformanceCounter>]
    01002F26  MOV     EAX, DWORD PTR SS:[EBP-C]
    01002F29  XOR     EAX, DWORD PTR SS:[EBP-10]
    01002F2C  XOR     ESI, EAX
    01002F2E  CMP     ESI, EDI
    01002F30  JE      SHORT 01002F3A
    01002F32  TEST    DWORD PTR DS:[__security_cookie], EBX
    01002F38  JNZ     SHORT 01002F3F
    01002F3A  MOV     ESI, BB40E64F
    01002F3F  MOV     DWORD PTR DS:[__security_cookie], ESI
    01002F45  NOT     ESI
    01002F47  MOV     DWORD PTR DS:[__security_cookie_complement], ESI
    01002F4D  POP     ESI
    01002F4E  POP     EDI
    01002F4F  POP     EBX
    01002F50  LEAVE
    01002F51  RETN

  7. #7
    Quote Originally Posted by blabberer View Post
    does it look like this
    blabberer, you're a genius, or a genii, if you have multiple personalities. That is the exact code, to a tee.

    What's with the magic number moved to the EDI early on....BB40E64E?? and where did you accumulate all this knowledge, it's uncanny.

    Still, I have TLS callbacks listed as:

    address of callbacks: C7DOBC
    address of callbacks: FA15D8
    raw data: B8A000
    virtual address: BA4000

    Are these offsets into the executable, or offsets after it is loaded? I don't see anything of interest after loading unless I add 400000 to C7D0BC, then there are a series of dwords. I have spent a couple of hours reading on TLS but so far no one has offered a solution. One article insisted that double-clicking on the TLS callbacks address in cff explorer would lead to the set of callback addresses but that does not work on my version.

  8. #8
    Quote Originally Posted by blabberer View Post
    doesnt ida recognize this and collapse this ??
    I should have looked there first...sorry. IDA listed it as a closed function called __security_init_cookie and that is followed by jmp __tmainCRTStartup. When I jump to __security_init_cookie, the code is laid out as you posted it but not collapsed.

  9. #9
    Super Moderator
    Join Date
    Dec 2004
    Posts
    1,508
    Blog Entries
    15
    it is a global that is compiled in the exe

    ULONG thiscrap = 0xbbXXXXXX;


    01004000 security_cookie BB40E64E N@
    01004004 security_cookie_complement 44BF19B1 D

    read this

    http://uninformed.org/index.cgi?v=7&a=2

  10. #10

    quotes suddenly not working

    The quotes feature is not working at present.

    You said..."read this http://uninformed.org/index.cgi?v=7&a=2"

    Thanks. Funny enough, I was just reading about that, I think on Matt Pietrek's article on SEH's. It seems the convoluted xoring was to get a unique cookie based on the present pid and tid. Is that correct?

    With regard to TLS, good old IDA provided the answer. Under 'Names' is a reference to TLSCallbacks. That leads to the address I inquired about for the TLS callback address. There are three pointer listed, to __rmtmp, __termcom, and __endstdio. From what I gather those funcs are related to cleanup and destructors, as Kayaker suggested. There are two other pointers I need to identify.

    Answering my own question from your article:

    "The guts of the __security_init_cookie routine are actually the most critical part to understand. At a high-level, this routine will take an XOR'd combination of the current system time, process identifier, thread identifier, tick count, and performance counter...". At least I can read a disassembly and understand it...to an extent. :-)
    Last edited by WaxfordSqueers; November 9th, 2012 at 15:59.

  11. #11
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,114
    Blog Entries
    5
    Quote Originally Posted by WaxfordSqueers View Post
    It's not clear to me how a TLS Callback would appear in Olly/softice. If code was called before the thread code was officially executed, would it show up in olly/softice as code addresses listed under the apps name, coming before the official app entry point?
    I suspected it was GsCookie code you were looking at, partly from the description and primarily because there is no default way to trace TLS Callbacks with Softice as far as I know. You can with Olly or IDA, perhaps Windbg, but not Softice.

    However, as they like to say in the mobile world, I have an App for that. It's a combination of PsSetCreateProcessNotifyRoutine and a redirection of TLS callbacks to injected code, with an option to break into Softice for tracing of the callback(s). If you're ever desperate to trace real TLS callbacks in Softice, let me know. Else just use IDA or the TLSCatch Olly plugin by Waliedassar here.

  12. #12
    Quote Originally Posted by Kayaker View Post
    If you're ever desperate to trace real TLS callbacks in Softice, let me know.
    Thanks K. No desperation, just trying to eliminate the anti-debug stuff.

    So far, it's looking like what Ork used to warn about, that I am giving programmers far too much credit for originality. Whereas some are very clever, the average one who writes an app does not seem that up on dirty tricks.

    Wrt to softice, why could you not catch the loading process farther back, along the lines of baseprocesstart as a bp? Surely there's a point in ntdll where it calls a function written by the programmer to do tls stuff.

    Speaking of which, I had a thread a while back complaining that I could no longer find _baseprocessstart in softice. I used to find it with an addr kernel32 and _baseprocesstart would be listed in the exports, if I had a k32 nms file loaded. I could then bpx on it. More recently, I cannot find it or used the addr command on k32. deroko told me you can't addr k32 because it does not have a process context.

    What was it we used to do to find _baseprocessstart? Before loading an app, I would change context into k32 and set a bp on _baseprocesstart. When I booted the app, ice would break at _baseprocessstart. I am not imagining that. It was a technique I used to trap an app with an obfuscated entry point.

    The major difference between IceStealth and IceExt just occured to me recently. With IceExt, you can use loader32 to reach the entry point then enable IceExt. You cannot do that with IceStealth. Once it is loaded, you cannot turn it off.

  13. #13
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,114
    Blog Entries
    5
    Sure, just make sure you've loaded the correct symbol table and grep for what you want. Isn't Softice wonderful?

    Code:
    :wc // turn code window off so you can dump this output with Loader32 "Save Softice History As"
    
    :table kernel32
    :sym _baseprocess*
    
          Address       Symbol Name
    .text(001B:7C801000, 00081C21 bytes)
        001B:7C8171BB _BaseProcessInitPostImport
        001B:7C816D2C _BaseProcessStart
        001B:7C810867 _BaseProcessStartThunk
        
    :table ntdll
    :sym *ldrp*tls*
    
          Address       Symbol Name
    .text(001B:7C901000, 0007A6FE bytes)
        001B:7C918E1D _LdrpAllocateTls
         001B:7C9284D9 _LdrpCallTlsInitializers => _LdrpCallInitRoutine // I'd trace this if you want the TLS callbacks ;)
        001B:7C919237 _LdrpFreeTls
        001B:7C9225DA _LdrpInitializeTls
    .data(0023:7C97C000, 000049E0 bytes)
        0023:7C97C048 _LdrpImageHasTls
        0023:7C97C168 _LdrpNumberOfTlsEntries
        0023:7C97C198 _LdrpTlsList

  14. #14
    Quote Originally Posted by Kayaker View Post
    Sure, just make sure you've loaded the correct symbol table and grep for what you want. Isn't Softice wonderful?
    Thanks K., worked like a charm that time. Can't see what I was doing wrong. I tried the table command before with no luck. Must have been a bad hair day.

    I think it may have had something to do with me having the exp for k32 turned off in winice.dat. I don't mean the nms file ref in winice.dat, I mean those near the bottom of the dat file that are often commented out.

    Would that not be a solution to tracing tls with ice? If you knew where the tls was called from in ntdll, could you not bpx on that, or are there no symbols for ntdll?

  15. #15
    Super Moderator
    Join Date
    Dec 2004
    Posts
    1,508
    Blog Entries
    15
    ollydbg 1.10 is wonderfull select the line
    Code:
    7C901176 ntdll.LdrpCallInitRoutine                /$  55              PUSH    EBP
    and press ctrl+r
    Code:
    References in ntdll:.text to LdrpCallInitRoutine
    Address                             Disassembly                                                   Comment
    7C901176 ntdll.LdrpCallInitRoutine  PUSH    EBP                                                   (Initial CPU selection)
    7C913A3E                            CALL    LdrpCallInitRoutine
    7C91B190                            CALL    LdrpCallInitRoutine
    7C91C4F5                            CALL    LdrpCallInitRoutine
    7C91E03F                            CALL    LdrpCallInitRoutine
    7C923AD5                            CALL    LdrpCallInitRoutine
    7C93CADB                            CALL    LdrpCallInitRoutine
    7C9570EA                            CALL    LdrpCallInitRoutine
    it will tell you where this tlsinit is called from
    and you can use ntglobalflagplugin by stingduk to catch tls callbacks (uses a primitive mechanism)

    [code]
    windbg is wonderfulls wunderfull
    it will tell you where this is called from with symbolic names as well
    Code:
    no selection nothing just type 
    # call*ntdll!LdrpCallInitRoutine ntdll L?0xb2000 
     notice regexp * and modname
    
    ntdll!LdrShutdownThread+0xd2:
    7c913a3e e833d7feff      call    ntdll!LdrpCallInitRoutine (7c901176)
    ntdll!LdrpInitializeThread+0xbb:
    7c91b190 e8e15ffeff      call    ntdll!LdrpCallInitRoutine (7c901176)
    ntdll!LdrpRunInitializeRoutines+0x33f:
    7c91c4f5 e87c4cfeff      call    ntdll!LdrpCallInitRoutine (7c901176)
    ntdll!LdrUnloadDll+0x417:
    7c91e03f e83231feff      call    ntdll!LdrpCallInitRoutine (7c901176)
    ntdll!LdrShutdownProcess+0x14a:
    7c923ad5 e89cd6fdff      call    ntdll!LdrpCallInitRoutine (7c901176)
    ntdll!LdrpCallTlsInitializers+0x7e:
    7c93cadb e89646fcff      call    ntdll!LdrpCallInitRoutine (7c901176)
    ntdll!AVrfpLoadAndInitializeProvider+0x111:
    7c9570ea e887a0faff      call    ntdll!LdrpCallInitRoutine (7c901176)
    and you can verify addresses match with ollydbg



    odbg 2 is even more whateverbull

    you can ask it to set bp on tls callbacks using its inbuilt option

    and it will break promptly on tls callback

    see a stack when it broke in tls call back

    Code:
    CPU Disasm
    Address                    Hex dump          Command                                  Comments
    00401068          /$  55            PUSH    EBP                              ; TLS callback function <----auto comment by odbg2
    00401069                   |.  8BEC          MOV     EBP, ESP
    0040106B                   |.  E8 E0FFFFFF   CALL    <JMP.&kernel32.IsDebuggerPresent ; [KERNEL32.IsDebuggerPresent
    Code:
    Log data
    Address   Message
               # ChildEBP RetAddr  Args to Child
              00 0013f9ac 7c90118a 00400000 00000001 00000000 mytls+0x1068
              01 0013f9cc 7c93cae0 00401068 00400000 00000001 ntdll!LdrpCallInitRoutine+0x14
              02 0013fa18 7c935e80 00400000 00000001 00030000 ntdll!LdrpCallTlsInitializers+0x83
              03 0013fb18 7c9211b4 0013fd30 7ffdf000 7ffd8000 ntdll!LdrpRunInitializeRoutines+0x48b
              04 0013fc94 7c9210af 0013fd30 7c900000 0013fce0 ntdll!LdrpInitializeProcess+0x1131
              05 0013fd1c 7c90e457 0013fd30 7c900000 00000000 ntdll!_LdrpInitialize+0x183
              06 00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7

Similar Threads

  1. Replies: 9
    Last Post: October 8th, 2008, 21:45
  2. Serial fishing
    By marco_ul in forum The Newbie Forum
    Replies: 15
    Last Post: March 14th, 2007, 09:53
  3. Serial fishing
    By warf in forum The Newbie Forum
    Replies: 6
    Last Post: March 4th, 2005, 10:54
  4. Serial fishing with Softice
    By newbcrk in forum The Newbie Forum
    Replies: 1
    Last Post: April 20th, 2003, 13:52

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
  •