View Full Version : 30 day trial license
ksbrace
January 9th, 2006, 14:07
Hello,
I am a newbie, so I thought the newbie forum would be a good place to start. I am working on a personal project that is a 30 day trial. I found the area that I think is relevant to the 30 day limit. I'm having difficulty finding the spot to skip the 30 day test. Any help would be greatly appreciated. Thanks in advance.
Kelly
Code:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62403C01(U)
|
:6240AADE B840C94C62 mov eax, 624CC940
:6240AAE3 E8084E0800 call 6248F8F0
:6240AAE8 51 push ecx
:6240AAE9 51 push ecx
:6240AAEA A194F64F62 mov eax, dword ptr [624FF694]
:6240AAEF 53 push ebx
:6240AAF0 56 push esi
:6240AAF1 57 push edi
:6240AAF2 8BF9 mov edi, ecx
:6240AAF4 8945EC mov dword ptr [ebp-14], eax
:6240AAF7 8365FC00 and dword ptr [ebp-04], 00000000
:6240AAFB 8945F0 mov dword ptr [ebp-10], eax
* Possible Reference to String Resource ID=00101: "Your license expires in %d days.
After this, you will need t"
|
:6240AAFE 6A65 push 00000065
:6240AB00 8D4DEC lea ecx, dword ptr [ebp-14]
:6240AB03 C645FC01 mov [ebp-04], 01
:6240AB07 E8E0AAFFFF call 624055EC
:6240AB0C 0FBF471C movsx eax, word ptr [edi+1C]
:6240AB10 50 push eax
:6240AB11 8D45F0 lea eax, dword ptr [ebp-10]
:6240AB14 FF75EC push [ebp-14]
:6240AB17 50 push eax
:6240AB18 E8B9A7FFFF call 624052D6
:6240AB1D 83C40C add esp, 0000000C
:6240AB20 8D7704 lea esi, dword ptr [edi+04]
:6240AB23 FF75F0 push [ebp-10]
* Possible Reference to Dialog: DialogID_0109, CONTROL_ID:01DC, "Static"
|
:6240AB26 68DC010000 push 000001DC
:6240AB2B FF36 push dword ptr [esi]
* Reference To: USER32.SetDlgItemTextW, Ord:0254h
|
:6240AB2D FF15D4115162 Call dword ptr [625111D4]
* Reference To: USER32.GetDlgItem, Ord:0111h
|
:6240AB33 8B1DD0115162 mov ebx, dword ptr [625111D0]
* Possible Reference to Dialog: DialogID_0109, CONTROL_ID:01DD, "I want to renew my license"
|
:6240AB39 68DD010000 push 000001DD
:6240AB3E FF36 push dword ptr [esi]
:6240AB40 FFD3 call ebx
:6240AB42 8D4F20 lea ecx, dword ptr [edi+20]
:6240AB45 50 push eax
:6240AB46 E860AAFFFF call 624055AB
:6240AB4B 85C0 test eax, eax
:6240AB4D 7408 je 6240AB57
:6240AB4F 8D4F20 lea ecx, dword ptr [edi+20]
:6240AB52 E82499FFFF call 6240447B
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:6240AB4D(C)
|
* Possible Reference to Dialog: DialogID_0109, CONTROL_ID:01E4, "I want to contact my nearest Dartfish re"
|
:6240AB57 68E4010000 push 000001E4
:6240AB5C C7477004000000 mov [edi+70], 00000004
:6240AB63 FF36 push dword ptr [esi]
:6240AB65 FFD3 call ebx
:6240AB67 8D5F78 lea ebx, dword ptr [edi+78]
:6240AB6A 50 push eax
:6240AB6B 8BCB mov ecx, ebx
:6240AB6D E839AAFFFF call 624055AB
:6240AB72 85C0 test eax, eax
:6240AB74 7407 je 6240AB7D
:6240AB76 8BCB mov ecx, ebx
:6240AB78 E8FE98FFFF call 6240447B
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:6240AB74(C)
|
:6240AB7D 6A00 push 00000000
* Possible Reference to Dialog: DialogID_0109, CONTROL_ID:01E3, "Do not display again"
|
:6240AB7F 68E3010000 push 000001E3
:6240AB84 C7435004000000 mov [ebx+50], 00000004
:6240AB8B FF36 push dword ptr [esi]
* Reference To: USER32.CheckDlgButton, Ord:0038h
|
:6240AB8D FF15CC115162 Call dword ptr [625111CC]
:6240AB93 8BCF mov ecx, edi
:6240AB95 E86AA1FFFF call 62404D04
:6240AB9A 6A00 push 00000000
:6240AB9C 8BCE mov ecx, esi
:6240AB9E E85CA6FFFF call 624051FF
:6240ABA3 8065FC00 and byte ptr [ebp-04], 00
:6240ABA7 8D4DF0 lea ecx, dword ptr [ebp-10]
:6240ABAA E86AAAFFFF call 62405619
:6240ABAF 834DFCFF or dword ptr [ebp-04], FFFFFFFF
:6240ABB3 8D4DEC lea ecx, dword ptr [ebp-14]
:6240ABB6 E85EAAFFFF call 62405619
:6240ABBB 8B4DF4 mov ecx, dword ptr [ebp-0C]
:6240ABBE 5F pop edi
:6240ABBF 5E pop esi
:6240ABC0 33C0 xor eax, eax
:6240ABC2 5B pop ebx
:6240ABC3 64890D00000000 mov dword ptr fs:[00000000], ecx
:6240ABCA C9 leave
:6240ABCB C21000 ret 0010
ksbrace
January 9th, 2006, 14:52
I have found a section related to errors. In this section there is a 'trial has expired' string. But, I also noticed a bunch of other scenarios that they are testing for. Thanks.
Code:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:6240240F(U)
|
:62487AE9 B8505A4D62 mov eax, 624D5A50
:62487AEE E8FD7D0000 call 6248F8F0
:62487AF3 83EC0C sub esp, 0000000C
:62487AF6 53 push ebx
:62487AF7 56 push esi
:62487AF8 57 push edi
:62487AF9 8BF9 mov edi, ecx
* Possible Reference to String Resource ID=00180: "Are you sure you want to delete %s? Deleting an identity
may"
|
:62487AFB 68B4000000 push 000000B4
:62487B00 6A01 push 00000001
:62487B02 8DB780000000 lea esi, dword ptr [edi+00000080]
:62487B08 6A01 push 00000001
:62487B0A 6A04 push 00000004
:62487B0C 8D4F7C lea ecx, dword ptr [edi+7C]
:62487B0F 56 push esi
* Possible Reference to Dialog: DialogID_01EE, CONTROL_ID:018F, ""
|
:62487B10 688F010000 push 0000018F
:62487B15 894DE8 mov dword ptr [ebp-18], ecx
:62487B18 E894ACF7FF call 624027B1
:62487B1D 85C0 test eax, eax
:62487B1F 0F8416010000 je 62487C3B
:62487B25 FF36 push dword ptr [esi]
* Reference To: OLEAUT32.SysAllocString, Ord:0002h
|
:62487B27 8B1D98105162 mov ebx, dword ptr [62511098]
:62487B2D FFD3 call ebx
:62487B2F 8945EC mov dword ptr [ebp-14], eax
:62487B32 8B8784000000 mov eax, dword ptr [edi+00000084]
:62487B38 8365FC00 and dword ptr [ebp-04], 00000000
:62487B3C 6A00 push 00000000
:62487B3E FF75EC push [ebp-14]
:62487B41 8B08 mov ecx, dword ptr [eax]
:62487B43 50 push eax
:62487B44 FF5138 call [ecx+38]
:62487B47 FF75EC push [ebp-14]
:62487B4A 834DFCFF or dword ptr [ebp-04], FFFFFFFF
:62487B4E 8BF0 mov esi, eax
* Reference To: OLEAUT32.SysFreeString, Ord:0006h
|
:62487B50 FF15E0105162 Call dword ptr [625110E0]
:62487B56 85F6 test esi, esi
:62487B58 0F8DFF000000 jnl 62487C5D
:62487B5E 8BC6 mov eax, esi
:62487B60 25FFFF0000 and eax, 0000FFFF
:62487B65 83F852 cmp eax, 00000052
:62487B68 7F35 jg 62487B9F
:62487B6A 742C je 62487B98
:62487B6C 83E84A sub eax, 0000004A
:62487B6F 7420 je 62487B91
:62487B71 83E805 sub eax, 00000005
:62487B74 7414 je 62487B8A
:62487B76 48 dec eax
:62487B77 740A je 62487B83 <-- Here, seems to send me to "expired", correct?
:62487B79 48 dec eax
:62487B7A 753F jne 62487BBB
* Possible Reference to String Resource ID=00267: "No Trial usage info."
|
:62487B7C B80B010000 mov eax, 0000010B
:62487B81 EB40 jmp 62487BC3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487B77(C)
|
* Possible Reference to String Resource ID=00270: "Your trial period has expired."
|
:62487B83 B80E010000 mov eax, 0000010E
:62487B88 EB39 jmp 62487BC3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487B74(C)
|
* Possible Reference to String Resource ID=00239: "License server hostname not specified correctly"
|
:62487B8A B8EF000000 mov eax, 000000EF
:62487B8F EB32 jmp 62487BC3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487B6F(C)
|
* Possible Reference to Dialog: DialogID_0109
|
* Possible Reference to String Resource ID=00265: "This license has been installed on the wrong machine"
|
:62487B91 B809010000 mov eax, 00000109
:62487B96 EB2B jmp 62487BC3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487B6A(C)
|
* Possible Reference to String Resource ID=00268: "Trial usage query failed"
|
:62487B98 B80C010000 mov eax, 0000010C
:62487B9D EB24 jmp 62487BC3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487B68(C)
|
:62487B9F 83E853 sub eax, 00000053
:62487BA2 741A je 62487BBE
:62487BA4 48 dec eax
:62487BA5 0F84A8000000 je 62487C53
:62487BAB 83E804 sub eax, 00000004
:62487BAE 0F8495000000 je 62487C49
:62487BB4 48 dec eax
:62487BB5 0F8484000000 je 62487C3F
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487B7A(C)
|
:62487BBB 6A53 push 00000053
:62487BBD 5E pop esi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487BA2(C)
|
* Possible Reference to String Resource ID=00269: "Error reading license file"
|
:62487BBE B80D010000 mov eax, 0000010D
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:62487B81(U), :62487B88(U), :62487B8F(U), :62487B96(U), :62487B9D(U)
|:62487C44(U), :62487C4E(U), :62487C58(U)
|
:62487BC3 8B0D94F64F62 mov ecx, dword ptr [624FF694]
:62487BC9 894DEC mov dword ptr [ebp-14], ecx
:62487BCC 50 push eax
:62487BCD 8D4DEC lea ecx, dword ptr [ebp-14]
:62487BD0 C745FC01000000 mov [ebp-04], 00000001
:62487BD7 E810DAF7FF call 624055EC
:62487BDC A194F64F62 mov eax, dword ptr [624FF694]
:62487BE1 8945F0 mov dword ptr [ebp-10], eax
:62487BE4 81E6FFFF0000 and esi, 0000FFFF
:62487BEA 8D45F0 lea eax, dword ptr [ebp-10]
:62487BED 56 push esi
:62487BEE C645FC02 mov [ebp-04], 02
:62487BF2 FF75EC push [ebp-14]
* Possible Reference to String Resource ID=00281: "The license code couldn't be added.
Reason: %s (%d)"
|
:62487BF5 6819010000 push 00000119
:62487BFA 50 push eax
:62487BFB E88FD2F7FF call 62404E8F
:62487C00 83C410 add esp, 00000010
:62487C03 FF75F0 push [ebp-10]
:62487C06 FFD3 call ebx
:62487C08 8945E8 mov dword ptr [ebp-18], eax
:62487C0B 8B4F50 mov ecx, dword ptr [edi+50]
:62487C0E FF75E8 push [ebp-18]
:62487C11 C645FC03 mov [ebp-04], 03
:62487C15 8B01 mov eax, dword ptr [ecx]
:62487C17 FF504C call [eax+4C]
:62487C1A FF75E8 push [ebp-18]
* Reference To: OLEAUT32.SysFreeString, Ord:0006h
|
:62487C1D FF15E0105162 Call dword ptr [625110E0]
:62487C23 8D4DF0 lea ecx, dword ptr [ebp-10]
:62487C26 C645FC01 mov [ebp-04], 01
:62487C2A E8EAD9F7FF call 62405619
:62487C2F 834DFCFF or dword ptr [ebp-04], FFFFFFFF
:62487C33 8D4DEC lea ecx, dword ptr [ebp-14]
:62487C36 E8DED9F7FF call 62405619
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487B1F(C)
|
:62487C3B 32C0 xor al, al
:62487C3D EB26 jmp 62487C65
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487BB5(C)
|
* Possible Reference to String Resource ID=00304: "The license has been invalidated due to clock tamper detecti"
|
:62487C3F B830010000 mov eax, 00000130
:62487C44 E97AFFFFFF jmp 62487BC3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487BAE(C)
|
* Possible Reference to String Resource ID=00283: "Error reading license information"
|
:62487C49 B81B010000 mov eax, 0000011B
:62487C4E E970FFFFFF jmp 62487BC3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487BA5(C)
|
* Possible Reference to String Resource ID=00190: "Your license has expired."
|
:62487C53 B8BE000000 mov eax, 000000BE
:62487C58 E966FFFFFF jmp 62487BC3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487B58(C)
|
:62487C5D 8B45E8 mov eax, dword ptr [ebp-18]
:62487C60 C60001 mov byte ptr [eax], 01
:62487C63 B001 mov al, 01
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62487C3D(U)
|
:62487C65 8B4DF4 mov ecx, dword ptr [ebp-0C]
:62487C68 5F pop edi
:62487C69 5E pop esi
:62487C6A 5B pop ebx
:62487C6B 64890D00000000 mov dword ptr fs:[00000000], ecx
:62487C72 C9 leave
:62487C73 C3 ret
naides
January 9th, 2006, 16:43
You posted a lot of uncommented code.
A cursory view of what you show us is that you are in the area that decides what message to display when the license is expired or otherwise bad.
DO NOT kill the messanger.
Appears that this area of code:
Code:
* Reference To: OLEAUT32.SysFreeString, Ord:0006h
|
:62487B50 FF15E0105162 Call dword ptr [625110E0]
:62487B56 85F6 test esi, esi
:62487B58 0F8DFF000000 jnl 62487C5D
:62487B5E 8BC6 mov eax, esi
:62487B60 25FFFF0000 and eax, 0000FFFF
:62487B65 83F852 cmp eax, 00000052
:62487B68 7F35 jg 62487B9F
:62487B6A 742C je 62487B98
:62487B6C 83E84A sub eax, 0000004A
loads a selector in eax that decides what message to display
Ask yourself: where does the eax value come from and what is necessary for a message saying "good boy" "you are registered" or something like that to happen.
You are nearby the protection mechanism, now analyze it. . .
SiGiNT
January 9th, 2006, 16:59
Of course naides is correct, changing what's moved into EAX may require finding a "hole" and replacing mov EAX, ESI with mov EAX, "good boy value" ,followed by a jump back to the next instruction - but the test ESI,ESI looks promising also.
SiGiNT
Actually considering all of the messages in the code are "bad ones" test EAX, EAX looks good also - OMG!

LLXX
January 9th, 2006, 22:16
With any time-limit protection, the first thing you should do is search for specific constants in the code. E.g. for 30 days:
1d = 29
1e = 30
1f = 31
278D00 = 2,592,000 i.e. the number of seconds in 30 days
9A7EC800 = 2,592,000,000 i.e. the number of milliseconds in 30 days

^ I remember this one from a few 30-day limits I've reversed.
Also, I'd look for any calls to Time-related APIs and follow the code from there.
naides
January 9th, 2006, 22:43
Looking at the first code you posted see my comments
Code:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62403C01(U)
|
:6240AADE B840C94C62 mov eax, 624CC940
:6240AAE3 E8084E0800 call 6248F8F0
:6240AAE8 51 push ecx
:6240AAE9 51 push ecx
:6240AAEA A194F64F62 mov eax, dword ptr [624FF694]; THIS AREA
IN MEMORY [634FF694] GIVES EAX ITS VALUE.
I BET IT HOLDS THE NUMBER OF DAYS LEFT IN THE TRIAL. FIGURE OUT
WHERE IN THE CODE [624FF694] GETS WRITTEN TO, AND YOU WILL SEE THE
TIME KEEPING MECHANISM
:6240AAEF 53 push ebx
:6240AAF0 56 push esi
:6240AAF1 57 push edi
:6240AAF2 8BF9 mov edi, ecx
:6240AAF4 8945EC mov dword ptr [ebp-14], eax
:6240AAF7 8365FC00 and dword ptr [ebp-04], 00000000
:6240AAFB 8945F0 mov dword ptr [ebp-10], eax; EAX IS THE ONLY VARIABLE PASSED TO THE 'TIME LEFT' BOX
* Possible Reference to String Resource ID=00101: "Your license expires in %d days.
After this, you will need t"
|
:6240AAFE 6A65 push 00000065
:6240AB00 8D4DEC lea ecx, dword ptr [ebp-14]
:6240AB03 C645FC01 mov [ebp-04], 01
:6240AB07 E8E0AAFFFF call 624055EC; THIS CALL PROBABLY DISPLAYS THE NUMBER OF DAYS LEFT IN SOME DIALOG BOX
MOST OF THESE TESTS PROBABLY NEED TO BE DONE BY LIVE TRACING THE CODE WITH A DEBUGGER AND PLACING BREAK POINTS
SiGiNT
January 9th, 2006, 23:47
Also keep in mind, it's important to observe the value that EAX contains - you probably can't just xor EAX instead of test EAX, frequently, I find that registers contain important values EG: memory locations - time trials have become, far more sophisticated than the used to be - also the values that LLXX mentioned are often combined with "some number" to disguise them, your code indicates that there is a machine ID and a Server involved, that would indicate that there is a file or registry value that contains the "first use date and a counter", as you can see there is an error for turning the clock back - you can search in Windows and sub-directories for a file that changed when the time trial ran out or if not expired yet one that changes each time you use it - occaisionally just deleting that file (or better yet rename it) - and I don't mean one of Window's index files - it probably would have a nonsensical name - searching through the executable with a hex editor in text mode for file names (start looking for .dll or .dat they frequently will be grouped together),may be helpfull, don't touch the .dll's just look for unique names. These files also can be found in doc's and settings. If you attempt to patch the trial, you'll often run into a second or third check. If you are fortunate enough to have 2 installations available you can set a bp on GetLocalTime and run a trace on an expired installation and compare it with a working one, and that can give you some clues as exactly what to patch.
SiGiNT
LLXX
January 10th, 2006, 05:37
Quote:
[Originally Posted by sigint33]that would indicate that there is a file or registry value that contains the "first use date and a counter", as you can see there is an error for turning the clock back - you can search in Windows and sub-directories for a file that changed when the time trial ran out or if not expired yet one that changes each time you use it - occaisionally just deleting that file (or better yet rename it) - and I don't mean one of Window's index files - it probably would have a nonsensical name - searching through the executable with a hex editor in text mode for file names (start looking for .dll or .dat they frequently will be grouped together),may be helpfull, don't touch the .dll's just look for unique names. These files also can be found in doc's and settings. |
A FileMon and a RegMon are especially useful for this. I've yet to see a file- or registry-based protection that escapes detection by those two, although there are some that will kill FileMon or RegMon if they find them in memory. This problem is easily solved by reversing and editing FileMon and RegMon so that they appear e.g. to be Notepad and Wordpad

ksbrace
January 10th, 2006, 14:55
Quote:
[Originally Posted by naides]You posted a lot of uncommented code.
A cursory view of what you show us is that you are in the area that decides what message to display when the license is expired or otherwise bad.
DO NOT kill the messanger.
Appears that this area of code:
Code: * Reference To: OLEAUT32.SysFreeString, Ord:0006h
|
:62487B50 FF15E0105162 Call dword ptr [625110E0]
:62487B56 85F6 test esi, esi
:62487B58 0F8DFF000000 jnl 62487C5D
:62487B5E 8BC6 mov eax, esi
:62487B60 25FFFF0000 and eax, 0000FFFF
:62487B65 83F852 cmp eax, 00000052
:62487B68 7F35 jg 62487B9F
:62487B6A 742C je 62487B98
:62487B6C 83E84A sub eax, 0000004A
loads a selector in eax that decides what message to display
Ask yourself: where does the eax value come from and what is necessary for a message saying "good boy" "you are registered" or something like that to happen.
You are nearby the protection mechanism, now analyze it. . . |
Ok, I am not sure what I'm looking for. I'm sorry for my ignorance. I guess all of the tutorials were just changing the jump lines to either the opposite(jg to jle, etc..) or nop'n them out. Now that I don't have directions in front of me on how to do it, it's not as easy as I thought. So, I was hoping for some more guidance. I did make a futile attempt at altering the above mentioned jump lines, but that only made matters worse.
I am using W32DASM and Hiew. Should I be using something else or is this enough for now. I took a peak at SI and it looks like it has a rather steep learning curve just to use the IDE. That isn't to say the learning curve is worth it, I'm just trying to figure out which route I should take. Thanks for your replies and your knowledge.
Kelly
Admiral
January 10th, 2006, 16:45
It's easy to waste lots of time patching & inverting conditional jumps all but at random, but it's rarely a good idea. If you happen to succeed with this then you've been lucky and you haven't really learned anything.
Analysing something like this from a dead-listing is not the easiest way to do it as it's very difficult to determine where the code has been called from (if anywhere) and the contents of most variables will be a mystery.
Any serious reverser will have a debugger in their arsenal in addition to your hex editor and disassembler. SoftICE is damned powerful but it's also (as good as) unsupported, very ugly (I know it sounds shallow) and not entirely easy to use. For what you're doing, a user-mode (ring3) debugger would be far better suited. The standard choice seems to be OllyDbg, although there are plenty of alternatives. Most tutorials you'll find are OllyDbg based, and in my opinion, OllyDbg is an excellent choice for newbies and veterans.
It'll probably take you an hour or so to get the hang of navigating the interface of whichever debugger you choose but once you've got the hang of it, you'll wonder how anybody gets by without live-tracing.
So my advice would be to get hold of a copy of OllyDbg (it's free), play around with it (maybe try out a few tutorials) for a while and once you're confident, have another bash at your target. Things should be a lot clearer. If you get stuck, come back and we'll help, but make sure you've got some evidence that you've spent some time on it.
Good luck
Admiral
naides
January 10th, 2006, 16:59
SoftIce is rather complicated. Consider downloading ollydbg and learn a little about live debugging and tracing.
You have started your path to reversing with disassembling/deadlisting, which is valid, perhaps the best way to analyse code, but debugging, live tracing allows rapid testing of hypotheses, and exploration.
1. download Ollydbg.
2. load your program into it.
3. place breakpoints in the areas of the code that you already identified.
3 carefully trace, step by step, around those areas and try to understand what the program is doing.
4. Then consider what you need to do to change the behavoir of the program. Randomly changing jmps around, sometimes works (does anybody here denies having sometime defeated a protection by changing a random jump and see what happens? ) but most of the times does not, until you find the RIGHT jump to change
SiGiNT
January 10th, 2006, 17:58
Absolutely! naides, I probably have patched nore jumps than I'd like to admit, but I think a better way to go is to actually make the value being examined pass the jmp requirement - ksbrace, you definitely need to be using a debugger, a trial that I'm currently working on has code similar, (however it's constantly self-modifying and not the same), and all the DS pointers are to memory addresses, and not values - yours is probably as described by naides but it's alway good to see what is going on and have the ability to try a modification on the fly.
SiGiNT
naides
January 11th, 2006, 14:21
KS:
I took a look at your software.
It is not the vanilla-type/newbie level protection, but it is not difficult either.
If you want to learn, I will give you some clues. Certainly the challenge could be quite motivation for you to learn asm and RCE. Let me know either here or in the PM what you want to do.
ksbrace
January 11th, 2006, 14:31
I definitely want to learn more about asm and RCE. So, whatever you have for me, I'll be glad to follow your lead. Thanks in advance.
naides
January 11th, 2006, 17:03
OK. Let us start with the fundamentals. time limit cracking 101.
There is a limited number of ways a program can ask the question: "what is today's date"
The windows API GetLocalTime, GetSystemTime are some of the most common. It can also read the time stamp of some file and then call FileTimeToSystemTime or other things of that nature.
In the disassembly you have look for these time related API. DoYou see one of them?
GetLocalTime It is called only once right here
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:62401627(U)
|
:624378C5 55 push ebp
:624378C6 8BEC mov ebp, esp
:624378C8 83EC18 sub esp, 00000018
:624378CB 8D45E8 lea eax, dword ptr [ebp-18]
:624378CE 50 push eax
* Reference To: KERNEL32.GetLocalTime, Ord:015Ch
|
:624378CF FF154C065162 Call dword ptr [6251064C]
:624378D5 8D45E8 lea eax, dword ptr [ebp-18]
:624378D8 8D4DF8 lea ecx, dword ptr [ebp-08]
:624378DB 50 push eax
:624378DC E83DC4FCFF call 62403D1E ; this call converts the date ant time
into a 64 bit float real and returns its value at ebp-08
:624378E1 DD45F8 fld qword ptr [ebp-08]; this isntruction pushes the date and time
real into the float stack using the MCF float time format
:624378E4 C9 leave
:624378E5 C3 ret
This piece of code runs after an unconditional jump from 62401627
but if you examine at that 62401627 area of the code you find
* Referenced by a CALL at Addresses:
|:624386B6 , :6243890B , :62438C75 , :62438D68 , :62439966
|:6243999D , :624399C8 , :624399E2 , :624399FE , :62439AC1
|:62439B22 , :62439C15 , :62439C89 , :62439F14 , :6243A87F
|:6243A967 , :6243A9B3 , :6243A9E0 , :6243AA21 , :6243AA4E
|:6243AA89 , :6243AB12 , :6243AB3F , :6243AB6F , :6243BC96
|:6243BCB8 , :6243BCEA , :6243BD22 , :6243BD6F , :6243BD8B
|:6243C02E , :6243C050 , :6243C082 , :6243C0BA , :6243C107
|:6243C123 , :62448E1D , :62448F9A , :62449B66 , :6244A18E
|:6244A1AA , :6244A29A , :6244A49C , :6244A53B , :6244A5B6
|:6244A5F7 , :6244A652 , :6244A6A3 , :6244A72B , :6244A80B
|:6244A897 , :6244A940 , :6244A9F2 , :6244AA25 , :6244AA7D
|:6244AAFF , :6244AB5D , :6244ABB2 , :6244AC5A , :6244AC8D
|:6244ACDA , :6244ADC8 , :6244B1EA , :6244B206 , :6244B222
|:6244B248 , :6244B72A , :6244B830 , :6244B89A , :6244B90E
|:6244BA9A , :6244BB25 , :6244BB86 , :6244BC11 , :6244BC7A
|:6244BCBE , :6244C152 , :6244EEBF , :6244EEFC , :6245042F
|:62460E1F , :624612CA , :6246146A , :624614D4 , :62462DF7
|:62463300 , :624636C8 , :624638A3 , :6246390E , :62463976
|:6246398E , :62463A56 , :62463BA1 , :62463D72
|
:62401627 E999620300 jmp 624378C5
aaarrghh. The time retreival function is called often and all over the place!!!
Do not despair. Only thing I want you to notice while you trace this code 'date cal'l in ollydbg is how the date information is returned. It will be important later on.
When for instance :624386B6 call the date and time code,
* Possible StringData Ref from Data Obj ->"Framework"
|
:624386B1 68C41F5062 push 62501FC4
:624386B6 E86C8FFCFF call 62401627; this call gets the date in the float stack. You saw it before
:624386BB 51 push ecx; opens 32 bits space at the top of the stack
:624386BC 51 push ecx; and another 32 bits total of 64 bits to the stack
:624386BD DD1C24 fstp qword ptr [esp]; this instruction unloads the date from
the float stack into the top of the regular stack
:624386C0 E855A1FCFF call 6240281A
:624386C5 8BC8 mov ecx, eax
:624386C7 E8C593FCFF call 62401A91
just remember the push ecx, push ecx, fstp series of instructions because they mark areas of the code where the program is checking the date.
Now the program may check the date for a variety of reasons including expiration time. How are you going to find out about time is up???
You tried looking some relevant strings, but there are too many of them.
Try this Install the program in another computer. Advance the clock more than 30 days, run the program. Note what the message tells you.
Set back the clock to the current date, notice the complaint message...
Now find those messages in the dead listing.
Digest what we have so far, and come back with questions
ksbrace
January 12th, 2006, 12:02
Code:
:624378DC E83DC4FCFF call 62403D1E ; this call converts the date ant time
into a 64 bit float real and returns its value at ebp-08
:624378E1 DD45F8 fld qword ptr [ebp-08]; this isntruction pushes the date and time
real into the float stack using the MCF float time format
Ok, this is what I'm thinking is happening for the 62378dc: it calls 62403d1e, which calls 624378ee, which calls the SystemTimeToVariantTime api. What I don't understand, is what does the E83DC4FCFF represent? In dec:997468732671
bin: 1110100000111101110001001111110011111111
I am understanding the fld a bit more thanks to:
http://courses.ece.uiuc.edu/ece390/books/artofasm/CH14/CH14-4.html#HEADING4-5
I don't understand what the dd45f8 means. Thanks in advance.
Anon
January 12th, 2006, 13:19
E83DC4FCFF is the hexadecimal code for "call 62403D1E." Likewise, DD45F8 is the hexadecimal code for "fld qword ptr [ebp-08]."
A deadlisting shows the offset of the code in the file, the hexadecimal code, and the more human-readable ASM equivalent of that code, usually in that order.
ksbrace
January 12th, 2006, 17:04
Ok, when I put a break point at 624378CF (GetLocalTime call.) and I analyze the first time it stops there. The EAX says: 0012FCCC, when I convert that to decimal I get 1244364, ECX: 0012FA60, decimal: 1243744
EAX: 0012FCCC, decimal: 1244364
ECX:0012FA60, decimal: 1243744
When I stop it at the return statement (624378E5):
EAX: 0012FCDC, decimal: 1244380
ECX: 0012FC88, 1244296
Now it stops there several, seemed like hundreds, of times.
naides
January 12th, 2006, 18:07
OK KS.
Do not panic.
I agree, catching the program checking the date and time is not going to takes us very far in this case, but you will see its use later.
I digress:
The current date and time is returned in a register on top of the the Float stack (not in EAX): in olly, you look at the registers window, you will see a column of registers labeled ST0, ST1....ST7
( If it does not, make sure that the registers title bar says "Registers (FPU)" click on it until it does)
At the moment 624378CF returns, ST0 holds a value like:
ST0 valid 38729.683402777780430
valid means it is a valid float format. The integer part, 38729 is today's date, counted in days since 1/1/1900, the begining of time according to Bill Gates.
The fractional part .683402777780430 is the fraction of a day, which can be converted to hours minutes seconds and miliseconds (0.5 means 12:00:00.000 noon)
If you fed this number to an excel cell and change the cell format to 'date' or 'time' you will obtain today's date and time. Excel uses the same ctime convention of the MFC
end digression.
Well think about this. This program is expired. Very early after you start, the program has to check the date, compare it with the install date, and because the difference is more than 30 days, issue a box saying: your trial period has now ended, then quit.
The problem is finding an area of the code that checks the time, then spits out the bad boy 'trial ended' message.
Notice that this actions are not necessarily contiguous, in fact they are not contiguous in the code (because the structure of programs, a call calls a call that calls a call that checks time, then another call makes the comparison, then another call calls a call that places a box saying 'bad boy'.
Can you find them? (Of course you can!
look who calls who, trace back in the code. Find the call that says bad boy and figure who calls it. either in deadlisting or during debugging. see who checks the time (remember the push ecx push ecx fstd series of instructions) before deciding to call the bad boy code.
If you need help, ask again
naides
January 13th, 2006, 10:54
Quote:
[Originally Posted by ksbrace]Ok, when I put a break point at 624378CF (GetLocalTime call.) and I analyze the first time it stops there. The EAX says: 0012FCCC, when I convert that to decimal I get 1244364, ECX: 0012FA60, decimal: 1243744
EAX: 0012FCCC, decimal: 1244364
ECX:0012FA60, decimal: 1243744
When I stop it at the return statement (624378E5):
EAX: 0012FCDC, decimal: 1244380
ECX: 0012FC88, 1244296
Now it stops there several, seemed like hundreds, of times. |
Sorry, I did not answer your question. Look at the coments.
The date and time are not returned at EAX, is a little convoluted
Code:
624378C5 /> 55 PUSH EBP; Typical call start frame
624378C6 |. 8BEC MOV EBP,ESP
624378C8 |. 83EC 18 SUB ESP,18 ; opens dec 24 bytes space in the
stack
624378CB |. 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]; load an address of the stack
in eax, the first time around indeed 0012FCCC
this is the address of the buffer that is going to contain the date and time
624378CE |. 50 PUSH EAX ; and pushes the pointer into the stack,
so getlocaltime 'knows' where to place the results ; /pLocaltime
624378CF |. FF15 4C065162 CALL DWORD PTR DS:[<&KERNEL32.GetLocalTi>; \GetLocalTime
624378D5 |. 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]; if you look at the ADDRESS
that was pointed by EAX 0012FCCC
(right click on the dump window and goto that address)
you will see what getlocaltime returns starting at 0012FCCC.
It is easier to see as word format.
right click the dump window in olly debug
and choose short, decimal or short, hex.
AT 0012FCCC You will see the year 2006 in dec,or 07D6 in hex,
the month 0001, the day of the week, 0005,
the day of the month, 000D in hex or 00013 in dec, hour min secs etc /pLocalTime format
624378D8 |. 8D4D F8 LEA ECX,DWORD PTR SS:[EBP-8] Loads the address of a buffer,
EBP-8 that is 8 byte long into ECX.
This buffer will contain the output of the next call.
624378DB |. 50 PUSH EAX ; pushes the address of the date in
pLocalTime, the input of the next call
624378DC |. E8 3DC4FCFF CALL XXXXXX.62403D1E ; Converts pLocaltime format to
ctime format (The float we discussed before) and
returns that value in EBP-8, the buffer pointed by ECX
624378E1 |. DD45 F8 FLD QWORD PTR SS:[EBP-8]; now loads the reformated date
into the float stack
624378E4 |. C9 LEAVE clean house dispose the temporary local variables
624378E5 \. C3 RETN; Return
ksbrace
January 13th, 2006, 13:03
Ok, I can see the current date at 0012FCCC. 000107D6 and then on the next line
0012FCD0: 000D0005 and so on for the minutes, seconds, etc.
Now, where is the date that they are comparing that to? I would think that if I set the compare date to something out into 2010 or later, that it won't expire. Or is there a way to bypass these calls altogether.
On another note, I installed on another box and set the date to a point where it expired. I got the 'your trial has expired' nag, I then set it back to the correct date and got a 'you have tampered with the date' alert box and then the 'buy a key' nag appeared.
So, if I fix the trial screen....what happens if I monkey around with the pc date? Would I get the 'you have tampered with the date' alert?
One more thing and this was somewhat bizarre. After I messed around with the date, I went into the registry and removed all of the app references and reinstalled. When I started it up, I got 'you have 2 days left of your trial' in the nag. So, I set my clock 3 days ahead and restarted teh app. It then said 'you have 364 days left of your trial'. Can you explain the 364 days part? Thanks,
Admiral
January 13th, 2006, 14:20
On the off-chance that you didn't notice, 364 = -1 (mod 365).
Seems strange to make such an operation though. Perhaps it's juts a coincidence.
ksbrace
January 13th, 2006, 14:54
yeah, I did realize that 364 was -1, but it just seemed odd.
naides
January 13th, 2006, 21:57
Quote:
[Originally Posted by ksbrace]Ok, I can see the current date at 0012FCCC. 000107D6 and then on the next line
0012FCD0: 000D0005 and so on for the minutes, seconds, etc.
Now, where is the date that they are comparing that to? I would think that if I set the compare date to something out into 2010 or later, that it won't expire. Or is there a way to bypass these calls altogether.
To be honest with you, I do not know. Finding out where the program stores the install date was not necessary to defeat the protection, so I did not search for it. The install date could be recorded in a variety of ways: at the registry, as seems to be the case in this program. In a unconspicuous file somewhre in the windows folder. in the time signature of some file. Often, in more than one place at the time. IT can be severly encrypted and unecognizable as a date.
On another note, I installed on another box and set the date to a point where it expired. I got the 'your trial has expired' nag, I then set it back to the correct date and got a 'you have tampered with the date' alert box and then the 'buy a key' nag appeared.
Yes. I saw that. If you find the code that generates those nag screens, you will find the heart of the protection
So, if I fix the trial screen....what happens if I monkey around with the pc date? Would I get the 'you have tampered with the date' alert?
The nag screens are the weakest link of the protection. Before deciding to show a nag, the program has to find out if the user is good or bad boy. That is what I used to defeat this particular protection. Preventing the program from showing the nag screen would be only 'shooting the messenger'. But if you know who the messanger is, you can backtrace who sent the 'bad boy message', and cahnge its behavoir.
One more thing and this was somewhat bizarre. After I messed around with the date, I went into the registry and removed all of the app references and reinstalled. When I started it up, I got 'you have 2 days left of your trial' in the nag. So, I set my clock 3 days ahead and restarted teh app. It then said 'you have 364 days left of your trial'. Can you explain the 364 days
part? Thanks,
No I can not explain it without performing some in depth analysis. You are playing the black box game. You change things around the program (registry keys) and observe the consequences in the program behavoir. IT is a valid approach, but I, personally would open the black box and find out where and how, the program calculates the 364 days in your trial message. Look up the API taht are used to read keys in the registry, and the registry ID that the program is reading. Lookup and download RegMon, and you will catch the program reading the registry.
|
As a bove in blue
ksbrace
January 14th, 2006, 13:22
Ok, when I set the clock on my pc to be beyond the trial, I set a break at :62480CBD.
Code:
* Possible Reference to Dialog: DialogID_007B, CONTROL_ID:016C, "To continue using this software you must"
|
:62480CAD 686C010000 push 0000016C
:62480CB2 FF7604 push [esi+04]
:62480CB5 FFD7 call edi
:62480CB7 8D8E74010000 lea ecx, dword ptr [esi+00000174]
:62480CBD 85C9 test ecx, ecx
:62480CBF 7403 je 62480CC4
:62480CC1 8B4904 mov ecx, dword ptr [ecx+04]
when it tests it goes to the next line, but it doesn't jump to 62480CC4.....
do I want it to jump?
naides
January 14th, 2006, 13:49
Well KS, there is one way to find out. Make it jump and see what happens.
test ecx,ecx: if ecx = 00000000 the zero flag is set (equals to 1)
je 6280CC4 jumps if equal, meaning if the zero flag is 1. If you look at it in the register window, z flag is 0. click on it and force it to 1. the jump WILL be taken.
But think about this: the code you are tracing constructs the nag screen that says: "you are expired" or something like that the decision to show that nag has been taken BEFORE this code is run. look above in the code, actually the call that calls this code, and you will see where the critical decisions are being made. YOU ARE CLOSE
ksbrace
January 14th, 2006, 22:32
I'm at address 62480C79 and there is a test ecx, ecx, when I put a break on that line and then click on the Z in the registers window to make it a 1. I was expecting the next line to jump to 62480C80. It seems no matter what I do, it doesn't jump to 62480C80. This seems to be the case for 62480C9E. I am not sure if I'm doing something wrong (probably) or not, but it just seems like those two tests never jump.
ksbrace
January 14th, 2006, 22:44
Ok, I'm not sure what I was doing, but it's jumping now and those aren't making a difference. So, I must not be at the right spot.
ksbrace
January 14th, 2006, 22:59
what about this push 1 at 62480CA5 and the push 30 at 62480CA8?
Admiral
January 14th, 2006, 23:56
ksbrace,
Understand that double-clicking a flag in OllyDbg will invert its status in the processor's context for your thread so that any conditional jump ('Jcc' is the general term, examples being JZ, JNZ, JB, JPO etc.) opcodes that follow will respond accordingly.
In natural execution, these flags are modified only by certain operations - mainly CMP and TEST (although many others such as XOR will have an effect). It is the next Jcc that 'reads' these flags and jumps or falls through accordingly. So modifying the appropriate flag after a CMP or TEST will change the behaviour of the following Jcc, provided nothing funny happens.
I'm not sure if you understood this process. If you did, I apologise for patronising you, but if not, it may explain why you were having trouble governing the flow of your target.
If you still don't understand, trace through your code with F7 & F8, keeping an eye on your EFlags register (and the bits that comprise it) as you step over CMPs and TESTs and watch how certain flags, (in particular the 'Z'ero flag) will change (or not change) according to the result of the comparison. The flag will retain its value until the next Jcc (it usually follows soon) is reached, which will jump accordingly.
It's also worth noting that some Jccs are synonyms. For example, JE (jump if equal) is identical to JZ (jump if zero). This may sound counterintuitive but it comes down to the fact that the zero flag is used both by TEST to identify zeros and by CMP to test equality.
So if I've said nothing else, I'll say that you should be inverting the value of the flag /after/ the TEST or CMP but before the Jcc, nowhere else.
Regards
Admiral
naides
January 15th, 2006, 11:26
KS: The point of this excercise is to introduce you (An other newbies that may read this ) to RCE.
At this point you are not closing into the protection. That is OK. I told you it was not a trivial protection.
The area of code you are tracing is NOT the center of the protection.
Let us give two steps backward and examine the big picture.
If you start the app after monkeying around with the date, you are greeted witn a MESSAGEBOX, that tells you 'No license has been found. . . '
If you look for this message 'No license has been found. . . ' you will find no less that 13 instances of 'Possible reference to . . .'., The majority of them are false positive.
As it happens, the identifier of this string 'No license has been found. . . ' is 0x110 whch is also a very common windows message ID, therefore that ocde is probably involved in message handling, not producing the nag. So who can we find the code that indeed displays the nag?
If you place a breakpoint to MessageBoxW, right when the app starts, you will break at the piece of code that generates the 'No license has been found. . . ' nag
at 62439700 it calls MessageBoxW (W means it is using Unicode strings).
A few lines above you see that the app
push 110 so this is where the nag is generated. . .
if you scroll above this piece of code, you see that here the program is going through a long 'case' structure that determines what nag to display. The proection is not here. If you change jumps above this MessageBoxW piece of code you only change the message displayed, not the behavoir of the program.
But if you find the call that called this code, either by looking in the call stack or by keep tracing until the ret instruction,
you get to code address 62438978.
Scroll up into this piece of code, and you will see that this code at 6243890B, checks the time,
Then calls some function
then checks a flag
6243892A . 66:83BF BC0100>CMP WORD PTR DS:[EDI+1BC],2
two times
Depending on the state of that flag jumps to the instruction that shows the nag, otherwise keeps going
Right here is where the protection is making the key decisions.
Learn its behavoir.
Look at what conditional jumps are taken when the program is OK and compare at what jumps are taken when the program is expired. either force the jumps or find out who controls the flags that direct those jumps...
ksbrace
January 17th, 2006, 13:04
I found your post very informative and interesting. Is that SOP to a breakpoint at MessageBoxW?
Also, I'm not quite sure I'm viewing the call stack window correctly or maybe I don't have the settings correct. I would have thought every call would be listed there, am I doing something wrong? Usually in java/c++ when debugging and using an IDE, I can see every call being made/was made. It seems when it's all done, all I see is the ntdll,msvcrt, and kernel32 calls.
Ok, so, for some reason, I can't seem to get rid of everything from the registry and so I was getting the "invalid license due to clock tampering".
I **think** I 'patched' that at address 6243962C, by changing the 0F85 to an 0F84. It now goes directly to "Your trial has now ended."
I guess I'm not sure if I killed the messenger or not.
So, I'm trying to work my way through the jumps that occur from address 6243892A, as you suggested.
I changed the jump at 62438932 to the following and watched whether it jumped or not, but I still get the "Your trial has now ended." nag screen no matter what I set that to.
70 - j0 didn't jump
71 - jn0 jumped
72 - jb jumped
73 - jnb didn't jump
74 - je didn't jump
75 - jnz jumped
76 - jbe jumped
77 - ja didn't jump
78 - js jumped
79 - jns didn't jump
7F - jg didn't jump
7E - jle jumped
7D - jge didn't jump
7C - jl jumped
7B - jp0 didn't jump
7A - jpe jumped
I'm not sure if that is what you wanted me to test or not, but that is what I did. On top of that, I wasn't sure if the 'clock tampering' issue was
causing this nag to appear or not. my other box took a big crap on Sunday and I need to get a new hard drive before I can have 2 machines back up.
Although, I thought about installing a vmware os just to test. Any help is always greatly appreciated. Thanks,
SiGiNT
January 17th, 2006, 16:17
This may be a different approach, rather than changing jumps and seeing what the effect is - set a bp at 6243892A run olly - it should break, use F8 to step thru the code - you should arrive at a call, (to a subroutine which is a jump to the nag), that when executed brings up the nag, look above in the code for a jump past that call, you can try forcing the jump past or modifying what it's testing to make the jump execute - see what happens.
SiGiNT
ksbrace
January 17th, 2006, 17:42
Ok, this is what I have discovered:
I put a break on 6243892A and F8 my way down to 624389DA calls 62405BDC which delivers the nag by calling 6243DA7F.
But there is a jump that skips over that section at 624389B1 if I change the z-flag and jumps to 62438AD3. From there, I F8 down and at 62438B44 there
is a je to 62438D1B and it doesn't jump. The next line is a cmp dword ptr ds: [edi+154],ebx. Then on the next line, there is a jnz to the 62438D1B (Same as 2 lines above) and it DOES jump.
I F8 my way down to 62438D5C and there is a jmp to 62438D9F and it does jump. From there, I keep F8'ng my way and I come to 62439CC9 adn there is a JNZ to 62439CE3 and it does jump.
I eventually come to another jump at 62439DE8 and it doesn't jump.
I eventually stop at 62439E10:
Warning:
The product is not licensed for this system. The application will not start. (picture of usb/parallel dongles).
Now, I don't know if I'm going forward or backwards as far as debugging this app goes.
Thanks again.
SiGiNT
January 17th, 2006, 18:18
You are definitely moving forward - before that jump is a test eax,eax if eax=0 then the jump will be taken, put a break on test eax,eax - you can change the eax value by clicking on it in the register window - run from that point and see what happens, if that works think of ways to change that value so that it will pass the test.
SiGiNT
naides
January 17th, 2006, 20:03
You are very close.
The only hurdle left to bypass is that last nag screen.
if you look at the code right above that call 62439E10 you will see a JGE. if you force it to jump, so the nag is not displayed, the program runs (at least in my box) and you are done.
NOW:
The hardest part was locating the protection.
just changing a few jumps you can make the program be an eternal demo.
Can you make it registered??
That is more challenging, but not impossible. Just locate and analyze.
Find the text that says thank you or something like that.
How does it feel?
SiGiNT
January 17th, 2006, 20:49
Hmmmm,
I just realized I hadn't expired the program - sooooooo - previous info deleted.
A word of caution this prog is sensitive to it's own name don't change it.
AND to clean it up a little simply change the read-only attribute in the <target>.ui file and remove the word Trial.
SiGiNT
Woodmann
January 17th, 2006, 23:37
Howdy,
I would LOVE to see a final report on this from ksbrace.
I could not be more happy about the fact that a few of you select people have taken the time to teach someone who has the basic skills

.
This is what the newbie forum should be about

.
Best regards, Woodmann
SiGiNT
January 18th, 2006, 02:47
Well,
Success, kinda! I think the clock setback is screwing everything up, I'm looking for a solution to that, with the setback patched and the xor eax.eax at 624389AF and with naides JGE patched the app runs but some features are missing - analyze brings up the unlicensed feature screen.
SiGiNT
ksbrace
January 18th, 2006, 11:12
Ok, I was about to pop the champagne last night and toast everyone here for their help and their time. When I made the last (at least I thought it was) patch last night and started the program, I also noticed what sigint33 already posted.
I'm getting a license error via an embedded html page( or at least it has the look and feel to an html page). When I click on the Analyzer icon/button, I'm missing all of the analyzation tools. It DOES playback video files under the Player icon/button.
I got my other box up and running thanks to a new hard drive and installed the app on there and I haven't toyed with expiring the clock because I wanted to have a working version to compare the differences.
Now, I have only made three mods to the exe:
1. 6243962C changed it from 0F87 to 0F84 (time tamper)
2. 624389B1 changed it from 0F84 to 0F85 (expired)
3. 62439DE8 changed it from 7D to 7C (dongle)
Looking back on this process, it reminds me of debugging any kind of app of a decent size. I have been working with an open source app called uPortal for the university I work for and the first time I took a look at it I was like "I'm never going find my way around." But as time went by, you get involved in the app and you know where to go and what to look for and actually know how to make changes correctly and even submit a couple changes back to the open source community. Very similar to this. So, I should have just been a bit more patient and tried to get my head wrapped around the app. Instead, I acted like a freshman taking their first programming course and just asking for too much help as soon as they get an error. I'm obviously not as comfortable with asm, so that in and of itself causes panic mode to set in early. I should have taken some more asm courses at school.
I think one of the biggest obstacles is learning a new IDE. This is the first time using a live debugger for asm, I have only previously used W32DASM and HIEW. Those that use it all of the time find it invaluable....and it is. Those who have never used it, find any IDE hard to use, hard to find things, etc...
Just like when you switch jobs or courses. One place may be a big .NET shop and you have to learn visual studio, then you get a new job and it's a java
shop and you are dealt with Eclipse or Intelli J or whatever flavor of IDE they are using. In fact, I'm still not sure how to PERMANENTLY edit the exe
file. I ended up opening HIEW and edit the lines in there. While I'm talking about the IDE, here's a funny/quirky situation. On my one box, I set some
breakpoints and when I reload(Ctrl-F2) the app, the breakpoints are there. On my other machine, everytime I reload, I have to reset the breakpoints. I have checked and double checked the settings and they appear to be identical. Is there a setting to save the breakpoints or is one of my machines not acting correctly? I also still don't think that the call stack and trace windows are giving me the info that I want to see. I'm not seeing every call made nor am I seeing anything in the run trace window. But, I've only been working with this IDE for a few days, so I just may be overlooking a setting or something.
I think the hardest part of this exercise was finding the protection scheme(s). Learning about putting a bp on MessageBox was an important learning tip and makes complete sense. Being patient and just stepping through the code is also a necessity.
Thanks for your help and I would like to continue on and get this to work 100%. Meanwhile, the champagne is on ice! Thanks again.
naides
January 18th, 2006, 13:59
Well, I most confess that I never ran the program much more than a few initial commands, so I did not notice the limited functionality because of the invalid license situation until SigInt pointed it out.
Weeelll, I myself ended out shooting the message and thinking that the bad news were going to go away.
Back to the drawing board.
KS: You have some idea where the license is being evaluated. around that 3. 64439DE8 changed it from 7D to 7C (dongle) . See where the code gets its good boy or bad boy information.
Also trace the app in a virgin box (or a VMware machine) and see how the "temporariy" valid license status is evaluated/read and you may open the bubbly soon thereafter
SiGiNT
January 18th, 2006, 15:16
naides,
I installed it fresh on a different machine last night - installwatch says it installs an incredible number of files outside the prog dir. and registry entries number in the hundreds - so killing the clock turned back may not be feasible. But the interesting thing is with the trial valid it bypasses the code at 643892A, so the decision may be made farther up in the code as to expired or not - I won't have time to play with it today, but maybe tomorrow - ksbrace - I patched the clock set back nag at a different place than you indicate, I can't find a 0F 85 at the address you list it's an 0F 87 and the nag appears before that address is reached - typo????
SiGiNT
ksbrace
January 18th, 2006, 15:30
sigint33,
Yes, it was a typo, it was 0F87..Now, I"m thinking that I should have maybe set it to OF86 instead of 0F84. If it doesn't jump with 0F87, then I should have set it to 0F86. 0F87 is jump if above. 0F86 is jump if below or equal, which would make more sense, right? I'm going to install it again and see if I can find anything.
ksbrace
January 18th, 2006, 16:01
Sigint33,
I overlooked part of your last comment. I made the change at 6243962C and I don't get the time tamper error. Where did you make your change that avoids the time tamper clock error?
SiGiNT
January 18th, 2006, 16:37
I am at work and don't have it installed on my laptop, but the jump I modified was the second jump below
CMP eax,59 - I tried it 2 ways I modified
CMP eax, 59 to
CMP eax, 58 that will do it also, but I finally chose to just modify the second jump down. Since you are unfamiliar with olly you should be able to find the spot easily by making the cpu window active hit CTL F and enter
CMP eax,59.
SiGiNT
Tip: on a jump near (0F8x), you can force a jump by changing it to 90E9, as on a jump short (7x), you can change it to EB.
Interesting side note I believe that second jump down is after a cmp ptr DS:xxxxxxxx, 0 - I changed cmp to mov and re-entered the jump that got blown away as a jmp not jcc and I ended up with a completely different reg screen - you had a choice of registering over the internet or not, if you choose not automatically you get a different serial number screen - one with the serial displayed and an activation code required - probably the same screen you would get if you fished the initial serial - good place for fishing.

test changed to
CMP
ksbrace
January 19th, 2006, 10:31
sigint33,
Ok, I was wondering if we had something diff. between us. I can find the cmp. Still working....
ksbrace
January 19th, 2006, 12:14
So, I set bp's at the following locations:
time tamper nag:
6243962C (my change)
6243896C (sigint's change)
expired nag:
624389B1
dongle nag:
64439DE8
the app breaks at address 6243896C, if I make it jump it does NOT stop at address 6243962C. IF I don't make it jump it does stop at 6243962C. If I don't make 6243962C jump it then goes to the next line 62439632(JMP DWORD PTR DS: and lands at Case 59 ('y') 624396A2 and eventually gets the time tamper msg creation at:
624396F8: generates title: "License Error"
624396FB: generates Text: "No license has been found to run the application....Reason: time tamper msg.
62439700: produces the nag
If I do make 6243962C jump, it goes to 6243972F (which has a label to the right "Default case of switch 62439626 and returns to 62438978 and then gets to 624389B1(expired nag).
Now, if I make it jump at 6243896C, it goes pretty much directly to 624389B1 (expired nag). So, which is correct? I would think that sigint33's change at address 6243896C is the right way, because it happens earlier than 6243962C.
I also noticed this at address 624388E7: UNICODE "ValidateLicense returned 0x%08x " Is this anything significant? I also saw it in another, possibly more than one, place. Is this relevant to anything?
naides
January 19th, 2006, 12:43
Some Progress Here:
Let me tell you how I did it because it is a nice technique:
http://woodmann.net/forum/showthread.php?t=5092&highlight=tutorial+time+trials
I installed a fresh copy of the program in a VM and ran in under olly
while I am tracing and expired/tampered copy under olly in the main system
I trace alternatively until I get to decision points and compare what is happening.
Everytime the app is preparing to tell me fuck-off, it calls 62404719.
In the non expired machine, it returns 00000000 in EAX
in the expired machine it returns things like 80004005 in eax.
I traced inside that call, and it is analyzing registry keys,coding and decoding and so on. If you force it to always return 00000000 in EAX, for instance by changing a mov EAX, ESI into XOR EAX,EAX right before the call returns, the FRONT application is now very forgiving regarding expiration dates and such.
However, when I try to run some functionality, the freshly install version inside the VM runs without problem, but the expired one complains, giving an error code that looks like 80004005
My hypothesis is that when you call some functionality, a module (Plug-Ins or dlls) gets loaded and the module code, independently, checks for a valid status of the license: temporary-non expired or permanent. the status of the "mother" application is inmaterial. (Probably you could by aditional modules and functionalities, each with an independent license)
Also observe that this protection is not trivial It probably forms part of a bigger license manager system which may use dongles and other methods)
One route to defeat this anomaly would be locate the license validation code in each module and neutralize it.
Another would be to reverse the license manager and produce a valid license file or registry.
We know the license validation code and if we run the app under regmon, we wolud see which keys are called by the FRONT app.
Then when we run one of the plug-in modules we will catch which file/dll is reading important registration keys. RegMon works well with OLLY so you can ieasily isolate the time segments in which the app is reading protection related registry keys (or files).
Any other ideas are welcome

SiGiNT
January 19th, 2006, 13:38
naides,
I observed pretty much the same as you, in a short time last night and in thinking about, patching out the license checks, I came to the conclusion that it would be like trying to patch a sieve - it does open some virtual modules, as well as other files when initializing - the no license found error HTML document is called from a virtual subdirectory called \PROTECT\, if you search for all analyzed strings you'll find that location PUSHed in three different routines - I think I will focus on code much earlier than we have been looking at and see if I can create a "first run" condition everytime the app initializes - a never-ending trial.
SiGiNT
Update, well I succeeded in stomping the clock-setback, but not in regenerating a new trial the clock setback info is apparently kept in one or 2 small dll's in the windows/system32 dir - on my machine they were called ssprs.dll with a corresponding ssprs.tgz and za4375a.dll also with a .tgz deleting them and reinstalling got rid of the error, but apparently the days remaining is kept buried in the reg. hive.
Almost there.......
the call to 62404719 is to a jump which shows calls from several different addresses - if you go to those addresses, every one, (except one which it never breaks on), is immediately followed by a test eax,eax changing all of these to xor eax,eax fixes everything that I can find - switch and create identities and other stuff, EXCEPT the analysis option.
SiGiNT
ksbrace would have to let me know since i don't have the codecs for the samples - so I've no idea if save or stuff like that is ok.
BTW
ksbrace - in reading your posts, it seems to me you are analyzing in olly and changing stuff with a hex editor - you can modify on the fly in olly just double click on the instruction and modify it to make it do what you want - for jumps olly will even calculate whether it's a short or near jump just enter jmp xxxxxxxx - watch out for accidently deleted subsequent instructions.
naides,
Any luck? - I traced through the sub that opens analyzer and it doesn't appear to be invoking anything other than system and IE dlls - I've tried acouple of patches but all that accomplishes is closing the library pane, no analyzer or no license found message, it does dig out a cslid number maybe that is the key.
naides
January 20th, 2006, 10:26
OK.
Fixing the analyzer protection has turned out to be a little more fun.
First of all, there is no "typical" nag. Just a HTML fomatted message in a white screen telling you are not licensed.
The HTM text is present in the main EXE file. I tried to put break points in text read, but Olly breaks deep inside windows modules, called by MFC42u through messages, so I was not able to swim back into the app code to catch it deciding to display the nag.
Change of front.
The HTML is a resource. With res hack I found that its resurce name is
\PROTECTED. also noticed the error code, 80004005 displayed by the resource. is not part of the text but is passed into it
As it happens
Code:
6242DFB2 . C645 FC 03 MOV BYTE PTR SS:[EBP-4],3
6242DFB6 . FFD7 CALL EDI ; <&OLEAUT32.#6>
6242DFB8 . 68 C0FD4F62 PUSH Name Removed.624FFDC0 ; UNICODE "res://"
6242DFBD . FF15 98105162 CALL DWORD PTR DS:[<&OLEAUT32.#2>] ; OLEAUT32.SysAllocString
6242DFC3 . 8945 0C MOV DWORD PTR SS:[EBP+C],EAX
6242DFC6 . 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
6242DFC9 . 50 PUSH EAX ; /String
6242DFCA . 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX ; |
6242DFCD . FF15 D0055162 CALL DWORD PTR DS:[<&KERNEL32.lstrlenW>] ; \lstrlenW
6242DFD3 . 50 PUSH EAX
6242DFD4 . 8D4D 0C LEA ECX,DWORD PTR SS:[EBP+C]
6242DFD7 . FF75 E8 PUSH DWORD PTR SS:[EBP-18]
6242DFDA . E8 A150FDFF CALL XXXXXXX.62403080
6242DFDF . 68 B0FD4F62 PUSH XXXXXXX.624FFDB0 ; ASCII "/PROTECTED"
6242DFE4 . 8D4D 0C LEA ECX,DWORD PTR SS:[EBP+C]
6242DFE7 . E8 9266FDFF CALL XXXXXXX.6240467E
6242DFEC . 53 PUSH EBX
This code reads the /PROTECTED resurce and displays it
if you look above in the code:
Code:
6242DF3B . 895D FC MOV DWORD PTR SS:[EBP-4],EBX
6242DF3E . 50 PUSH EAX
6242DF3F . 68 54314E62 PUSH XXXXXXX.624E3154
6242DF44 . FF75 0C PUSH DWORD PTR SS:[EBP+C]
6242DF47 . E8 D933FDFF CALL XXXXXXXX.62401325; This call returns 80004005 if non registered or 000000000 if registered
6242DF4C . 83C4 0C ADD ESP,0C
6242DF4F . 3BC3 CMP EAX,EBX
6242DF51 . 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
6242DF54 . 53 PUSH EBX
6242DF55 . 0F8D DE000000 JGE XXXXXXXXX.6242E039; If EAX is 0 (becasue EBX is made 0 above) it jumps ahead of the bad boy nag otherwise EAX is 80004005 and the nag and the error are displayed
BUT: just forcing EAX to be 0 does not do the trick.
Digging into it, the call to 62401325 validates an creates a COM object Which is none other than the analyzer module.
using the instruction:
Code:
6241FAFD |. FF15 A8165162 CALL DWORD PTR DS:[<&ole32.CoCreateInsta>; ole32.CoCreateInstance
In the good boy version, it writes a handle to the Instance to a buffer in the stack. In the expired, tampered version, it writes 00000000 so the COM Object has no handle then the analyzer does not run.
I stand by my theory that the Analyzer COM object constructor validates the
good boy status and refuses to load if the app is expired
My problem now is locate the code of the COM object. A little out of my league, because I am not a programmer, much less a COM programmer.
Q: How do COM objects look like? are they DLL, are they embeded inside other modules, are they self standing files?
Is it possible to catch a COM object being loaded or created?
Thanks for any help
ksbrace
January 20th, 2006, 14:57
well, com objects are usually dll, ocx, active x components which are dll or ocx. There is a tool called comspy(http://staff.develop.com/jasonw/comspy/default.htm), although it appears to be somewhat outdated, that may be able to help and there is an app called ANTS memory profiler(http://www.c-sharpcorner.com/EditorContent/DisplayReview.aspx?ReviewID=11), not sure if the ants profiler is the right tool.
I have done some com programming. When using MS's tools, they aren't anything special. Visual Studio does all of the COM interfacing for you. When you write your own COM objects via C/C++ it gets a lot more involved.
Not sure if this helps or not.
I'm bogged down today at work, so I can't play with this until tonight.
naides:
if you aren't a programmer, what do you do, EE?
SiGiNT
January 20th, 2006, 15:56
I'm going to take a little different tack, the problem seems to be all located in the call directly below 6242DEAF - If I recall correctly it loads an external .dll address into EAX and other registers are modified - if tonight I can force it to return with the correct register values, then that may do the trick, unless there actually is some validation going on in the external process - then I'm back to square 1 - I did load some mpegs into it and save and other functions seem to be working correctly - so it appears this is the last hurdle (famous last words!)
SiGiNT
Why do I think there is someone out there that already has this puppy up and running and they are watching this thread and chuckling.

naides
January 20th, 2006, 16:10
Quote:
[Originally Posted by ksbrace]naides:
if you aren't a programmer, what do you do, EE? |
I mostly work as a serpent charmer and women tamer. . .
I've done my share of bar tending, floor sweeping and mopping in my time,
I've been Valet driver at Valet parking
Some of this, some of that,
When hungry,
I excel at crying at funerals
And my eulogies are quite poetic,
In court,
I am quite convincing as a legal expert witness
And perjury myself for a small extra fee
I spend my days solving puzzles,
The hardest kind,
avoiding real work like the plague
But when real plagues finally arrive,
I'll have no option but to solve plagues as puzzles
So there are no so many funerals to cry
JMI
January 20th, 2006, 16:50
naides:
You missed one instance of the "name" of the target in the code you Posted above.

I have removed it for you.
Regards,
SiGiNT
January 20th, 2006, 17:07
naides,
As to your occupation I've done pretty much the same largest difference is change Expert Witness to "defendant", and the perjury is free!!
SiGiNT
Oh yeah, and if you are right and the decision is made and handle assigned before the call I mentioned then I'll be wasting my time - but I'm stubborn and gonna do it anyway.
naides
January 20th, 2006, 17:40
Thanks JMI. I'm sorry for the overlook.
Too much code for a single day. . .
I've got to start using a word processor to write my posts and do spell check and such
SiGiNT
January 21st, 2006, 01:37
I must have been freakin hallucinating last night! there is absolutely nothing going on in the sub. called after 6242DEAF. Shit back to the drawing board!
SiGiNT
Kayaker
January 21st, 2006, 02:43
Quote:
I spend my days solving puzzles,
The hardest kind,
avoiding real work like the plague
But when real plagues finally arrive,
I'll have no option but to solve plagues as puzzles
So there are no so many funerals to cry
|
Eloquent poetry naides. It gives me visions of something like a tortured medical researcher bracing for the onslaught of avian flu or similar epidemic, shoring up the frontlines of research on a cure to the benefit for generations of all mankind...
Of course it could mean 'squat too, but hey, poetry is supposed to "speak" to you

LLXX
January 21st, 2006, 06:01
As I have not actually seen this particular target I will speak merely in generalities. Although many of us derive pleasure from reading through code and watching the operation of a program, I cannot stress enough the countless times I have been able to defeat a software protection not by wading through inenumerable lines of code, but by systematically observing the data used by the protection. Reversing is not only about being able to understand code, but about understanding how code and data interact.
So, when the code becomes laborious and difficult, it may be time to consider another approach. Take a new perspective on the situation and be creative in your efforts. Work smarter, not harder.
@naides: Your poetry is very inspirational. Good work!

SiGiNT
January 21st, 2006, 14:37
Activation request by e-mail or fax
<target> requires that you activate this product in order to verify that you are installing an authentic <target> product. During activation, the product creates a unique hardware identifier that represents the configuration of the computer at the time of activation. Activating your product is a one-time operation and involves three steps:
1. You insert your product key.
2. You request an activation code.
3. You receive back your activation code and enter it
Sentinel Emulator anyone???
Actually I don't think a simple emulator will do it, in reading through the Sentinel code it looks for specific features activated and other info - not just the fact that the hardlock is installed.
SiGiNT
naides
January 21st, 2006, 14:59
KS and SIgInt:
I have been doing some deep code diving to get to this point, but hey
Look at this code. It is invoked every time you ask for a service (Click a button or pick a service form the menu) and works OK except with the Analyzer
Code:
6241FAA3 /> 55 PUSH EBP
6241FAA4 |. 8BEC MOV EBP,ESP
6241FAA6 |. 83EC 10 SUB ESP,10
6241FAA9 |. 53 PUSH EBX
6241FAAA |. 8B5D 10 MOV EBX,DWORD PTR SS:[EBP+10]
6241FAAD |. 56 PUSH ESI
6241FAAE |. 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
6241FAB1 |. 8323 00 AND DWORD PTR DS:[EBX],0
6241FAB4 |. 57 PUSH EDI
6241FAB5 |. 85F6 TEST ESI,ESI
6241FAB7 |. BF 05400080 MOV EDI,80004005
6241FABC |. 74 4B JE SHORT XXXXXXX.6241FB09
6241FABE |. 66:833E 00 CMP WORD PTR DS:[ESI],0
6241FAC2 |. 74 45 JE SHORT XXXXXXX.6241FB09
6241FAC4 |. 56 PUSH ESI ; /String = "{7E9DCADA-2B97-419B-94A6-F414C92087BB}" This is the Analizer COM CLSID
6241FAC5 |. FF15 D0055162 CALL DWORD PTR DS:[<&KERNEL32.lstrlenW>] ; \lstrlenW ;Check the size if the string
6241FACB |. 3D FF000000 CMP EAX,0FF
6241FAD0 |. 73 33 JNB SHORT XXXXXXX.6241FB05
6241FAD2 |. 66:833E 7B CMP WORD PTR DS:[ESI],7B ; Make sure it starts with the right bytes
6241FAD6 |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
6241FAD9 |. 50 PUSH EAX
6241FADA |. 56 PUSH ESI
6241FADB |. 75 08 JNZ SHORT XXXXXXX.6241FAE5
6241FADD |. FF15 8C165162 CALL DWORD PTR DS:[<&ole32.CLSIDFromStri>; ole32.CLSIDFromString; And turns it into binary CLSID pointed by ESI at [EBP-10]
6241FAE3 |. EB 06 JMP SHORT XXXXXXX.6241FAEB
6241FAE5 |> FF15 90165162 CALL DWORD PTR DS:[<&ole32.CLSIDFromProg>; ole32.CLSIDFromProgID
6241FAEB |> 8BF8 MOV EDI,EAX
6241FAED |. 85FF TEST EDI,EDI
6241FAEF |. 7C 14 JL SHORT XXXXXXX.6241FB05
6241FAF1 |. 53 PUSH EBX
6241FAF2 |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]; Loads CLSID address into EAX
6241FAF5 |. FF75 0C PUSH DWORD PTR SS:[EBP+C]; This is where the handle to the Class will be returned: 00 if the class refuses to load
6241FAF8 |. 6A 15 PUSH 15
6241FAFA |. 6A 00 PUSH 0
6241FAFC |. 50 PUSH EAX ; Push First parameter for the CoCreateInstance API, the CLSID
6241FAFD |. FF15 A8165162 CALL DWORD PTR DS:[<&ole32.CoCreateInsta>; ole32.CoCreateInstance
6241FB03 |. 8BF8 MOV EDI,EAX; EAX returns 00 on success, 80004005 when the COM mod is protected and refuses to load
6241FB05 |> 8BC7 MOV EAX,EDI
6241FB07 |. EB 02 JMP SHORT XXXXXXX.6241FB0B
6241FB09 |> 33C0 XOR EAX,EAX
6241FB0B |> 5F POP EDI
6241FB0C |. 5E POP ESI
6241FB0D |. 5B POP EBX
6241FB0E |. C9 LEAVE
6241FB0F \. C3 RETN
I have, for instance, replaced the the CLSID string {7E9DCADA-2B97-419B-94A6-F414C92087BB} with the string associated with soem of the other COM objects invoked by other buttons, and it loads seamlessly the other COM object.
Ergo the Analyzer COM itself is guilty of refusing to load.
Now, where is the file that contains the code associted with this COM module?
If we look in the registry for {7E9DCADA-2B97-419B-94A6-F414C92087BB}
We find that this CLSID is associated with a dll named XX_XXXpack.dll
actually if I trace the code above until right before the instruction
6241FAFD |. FF15 A8165162 CALL DWORD PTR DS:[<&ole32.CoCreateInsta>; ole32.CoCreateInstance
and turn on the
Break in new module DLL option in OLLY, the Debugger breaks and you can see that XX_XXXpack.dll module being loaded during the CoCreateInstance execution.
I traced inside the ole32.CoCreateInstance call for a little while and found so far that
Code located at 64539BB9 inside XX_XXXpack.dll gets invoked from within ole32.CoCreateInstance. This and/or the dll entrypoint code probably determine the good boy/bad boy status of the app.
Now I am going to trace that XX_XXXpack.dll while it is being loaded in the good app and the expired app in parallel and look for differences
ksbrace
January 21st, 2006, 19:58
At this point, I'm basically just trying to do whatever you guys post and follow your lead. This is the most complex protection scheme I've ever played with and don't really know how to lend a hand.
SiGiNT
January 21st, 2006, 20:10
I've been tied up all day - but ksbrace, if this is a pure dongle protection scheme, usually reversing it by patching is difficult if not impossible - most turn to using an emulator - however the fact that we've gotten this far is really encouraging - don't know if I'll have a chance tonight - but if I do I'll report back.
SiGiNT
naides
January 21st, 2006, 20:33
Quote:
[Originally Posted by sigint33]I've been tied up all day - but ksbrace, if this is a pure dongle protection scheme, usually reversing it by patching is difficult if not impossible - most turn to using an emulator - however the fact that we've gotten this far is really encouraging - don't know if I'll have a chance tonight - but if I do I'll report back.
SiGiNT |
Yes and No SigInt:
At least while the program is in Demo, during the 30 days trial, it runs without a dongle. . .
All the code is here,
And doubt the dongle holds some irreplaceble key tht is not present at the app during the demo period.
So I think there is hope.
SiGiNT
January 22nd, 2006, 02:35
naides,
Absolutely, and a couple of posts back I mentioned trying to renew the trial, and make it "never endeng", unfortunately, I deviated from that - while you are deep in that weird-ass dll, I'll be exploring that possibility - that .dll does have a external time function.
SiGiNT
naides
January 22nd, 2006, 12:15
Victory at last!
I finally found the code in XX_XXXpack.dll that prevents itself from loading in the expired status.
It took some systematic diving into the code, but it was not all that difficult, just boring
Remeber
Code:
6241FAFD |. FF15 A8165162 CALL DWORD PTR DS:[<&ole32.CoCreateInsta>; ole32.CoCreateInstance
6241FB03 |. 8BF8 MOV EDI,EAX; EAX returns 00 on success, 80004005 when the COM mod is protected and refuses to load
So I traced In to the call, right inside OLE32 module and kept and Eye on EAX.
Every time some call returned 80004005 in EAX, or the code moved that bad boy flag in EAX, I studied the code and traced into the call that was responsible. Simultaneously, I had the fresh app installed in a VM so I could check the code bahavoir when App was OK.
Eventlually OLE32 performs an undirect call into XX_XXXpack.dll leading to address 64539989 inside the dll.
I kept doing the same thing, tracing into calls that return the bad boy in EAX
until I landed at some code about 12 levels of calls away from the main app code
|
Code:
:64517DA8 51 push ecx
:64517DA9 51 push ecx
:64517DAA 81C1B5020000 add ecx, 000002B5
:64517DB0 8BC4 mov eax, esp
:64517DB2 89642404 mov dword ptr [esp+04], esp
:64517DB6 68A8255C64 push 645C25A8
:64517DBB 832000 and dword ptr [eax], 00000000
:64517DBE E8AE94FEFF call 64501271
:64517DC3 85C0 test eax, eax
:64517DC5 7D07 jge 64517DCE
:64517DC7 B805400080 mov eax, 80004005
:64517DCC 59 pop ecx
:64517DCD C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:64517DC5(C)
|
:64517DCE 33C0 xor eax, eax
:64517DD0 59 pop ecx
:64517DD1 C3 ret
Right there! force EAX to return 00000000 instead of 80004005 and Viola,
OR if you are a purist, find out what that call 64501271 does. It needs to return 0 in EAX
SiGiNT
January 22nd, 2006, 15:54
Naides,
Excellent work!! - kudos!!
I'm still going to investigate the endless trial just for fun - my wife chained me to the living room sofa last night and forced me to watch a movie, but, I did find out that the days remaining is stored in a cslid that is located in documents and settings/all users/application data/<target>/<target> as well as in the registry in at least 1 place, maybe more.
ksbrace,
That dll is actually XX_XXXXXPACK.DLL where the third X after the underscore is part of the name - you can either force the JGE or change test eax, eax to xor eax, eax - doesn't matter - now we need you, (since you are familiar with this <target> to let us know if it's fully functional - before you pop the cork and don't forget to have a toast to naides!
SiGiNT
Oh and just for giggles I expired my one still good demo and applied everything, and all is well, when the demo period reaches 0 it rolls over to 364 days.
ksbrace
January 23rd, 2006, 10:42
Ok, I'm looking to apply all of the patches and give it a test, but I'm not sure what is ruled out and what patches are needed. If you don't mind, would you tell me which of the following edits are needed? Also, I'm not sure as to which XX_XXXXXPACK.DLL file needs to be touched. I do see a lot of dll's in the C:/Program Files/Target/Target software/bin directory, but there are several that fits the xx_xxxpack.dll.Thanks in advance!
(Post #40):
1a. 6243962C changed it from 0F87 to 0F84 (time tamper)
1b. 624389B1 changed it from 0F84 to 0F85 (expired)
1c. 62439DE8 changed it from 7D to 7C (dongle)
(Post #45):
2. 6243896C (sigint's change for time tamper)
(Post #49):
3. the call to 62404719 is to a jump which shows calls from several different addresses - if you go to those addresses, every one, (except one which it never breaks on), is immediately followed by a test eax,eax changing all of these to xor eax,eax fixes everything that I can find - switch and create identities and other stuff, EXCEPT the analysis option.
(Post #66):
4. B805400080 mov eax, 80004005
force EAX to return 00000000 instead of 80004005
SiGiNT
January 23rd, 2006, 11:49
Quote:
[Originally Posted by sigint33]
Almost there.......
the call to 62404719 is to a jump which shows calls from several different addresses - if you go to those addresses, every one, (except one which it never breaks on), is immediately followed by a test eax,eax changing all of these to xor eax,eax fixes everything that I can find - switch and create identities and other stuff, EXCEPT the analysis option. |
This plus the change test eax,eax to xor eax, eax at 624389AF in addition to naides chabge to XX_XXXXXpack.dll, (the third X from the underscore is a valid letter, only 1 dll matches this criteria), is how I'm running this. to find the addresses called at the jump that 62404719 hit enter at 62404719 then click on the addresses shown below the cpu window and right click you can go to them one at a time. I would have changed the sub that the jump goes to so that it returns 000000000 in eax but I didn't see a way that I was comfortable with.
SiGiNT
ksbrace
January 23rd, 2006, 11:53
well, there are actually 2 that fit the criteria. There is one with an Upper case X, which is the one I was looking at, and the one you are talking about, which is lower case. making the changes momentarily. Thanks,
Nevermind, there is only one that fits the criteria. It's monday!!!!
ksbrace
January 23rd, 2006, 12:23
Ok, everything seems to be working like it should, but I am at work and don't have my video cam to be sure about the import options. I will grab it during lunch and give it a test.
Ok, I made 3 changes in total:
1. 6243D8C2 : mov EAX, ESI
to
6243D8C2 : xor EAX,EAX
2. 624389B1 changed it from 0F84 to 0F85 to get rid of the time trial nag.
3. in external dll file:
:64517DC7 B805400080 mov eax, 80004005
change to
:64517DC7 B805400080 mov eax, 00000000
All in all, it was a great tutorial. I wish I could have been more of a player than a spectator, but I'm sure I will get my time, soon enough. Anyway, thanks again for all of the help and some great tips for the next target.
In order for you to figure out that the external dll was of interest, what did you do...just keep stepping into every call?
SiGiNT
January 23rd, 2006, 13:49
I'm pretty sure thats how naides did it - quite time consuming, but there are some shortcuts, when you are in a system dll hit CTL F9 then F7 at the return, another clue, would have been watching the executables window, the .dll in question, is added to the list when you try to invoke the analyzer. This also would have made finding the dll easy after naides posted the code the base address and length in the executables window, matched the line numbers that naides posted.
SiGiNT
naides
January 23rd, 2006, 16:58
Quote:
[Originally Posted by ksbrace]
In order for you to figure out that the external dll was of interest, what did you do...just keep stepping into every call? |
Well no. . .
It was a brutal force attack, but not all that brutish
I learned the functionality of the CoCreate API, and figured the meaning of the CLSID that were being passed into the function.
The Registry told me what .dll file this COM module was contained in.
If you trully trace into each call, you would spend the rest of your useful life tracing through system code, some times repeatedly. That was not what I did.
I had a clear goal, the first time the XX_XXXXXpack.dll code got invoked,
and a gauge for the right path: If 80004005 value was passed into EAX, I had missed my call to trace into.
I also had the most important element, which is based on a method that Kayaker described a few years ago.
I simul-traced in the non-expired app and the expired app
and stopped when their behavoir diverged. . .
As of time consuming, It took me about 1/2 hour to set up everything in the VM and OLLY, then about 70 mins to hit gold
I am sure most of this process could be automated using run-trace F7 and conditional break-points.
SO
It was not all that time consuming or brute force as it seems
SiGiNT
January 23rd, 2006, 18:23
naides,
I found out very early this app would detrect that it was being debugged if I did a run trace - and terminate with a message from hide debugger that it was unable to evade detection and prevent termination.
SiGiNT
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.