Log in

View Full Version : NetCaptor 7.1.0 - new tricks


xybyre
March 12th, 2003, 18:11
I've just patched the latest NetCaptor, v7.1.0. I was just wondering if anybody else had difficulties with this program...

Previous versions were packed with aspack, I believe. This one seemed to be packed with UPX. I manually unpacked this one, since I could. I never could unpack an asprotected proggie manually... (thank goodness for aspackdie)

anyway, the new trick here is putting the tamper-checks in exception handlers, and when it detects something wrong, a new instance of NetCaptor is created and the current process terminates. The newly-created process displays the "bad cracker" dialog.

If you break in the function that terminates the program, you don't get a call stack because of the SEH. So how do you know what code called the current function? The answer for me was IDA. IDA pointed out all of cross-references to the function and allowed me to track down the bad-cracker-check function.

It's kind of ironic, though. Now all of their bad_cracker checks call the same function to display the nag and quit. So one patch takes care of it all. (okay, there's another patch for the reg flag, but that's not really worth mentioning)

In cases like this, is there a way to find out the caller of a function without requiring the use of IDA?

S3ri@l CoDe9x
March 12th, 2003, 21:04
I really never try to crack this app , i post one tutorial for this version, ( Thanx Real|sty/TSRh )


I hope that this can help u!



Best Regards!

Solomon
March 12th, 2003, 21:04
nice work. But really new tricks? Maybe these tricks have been there for many versions. It can be "unpacked" with an "UPX -d NetCaptor.exe" now. And it can be patched in 10 minutes after disasm, including the size_check/invalid_key_check.

Just search for "65537"(which is the public exponent of RSA, implemented with FGInt) in the dead-listing, key validation routine can be located and the registered_or_not flag can be found.
Code:

CODE:00506FC3 call System::_16823
CODE:00506FC8 cmp eax, 96h
CODE:00506FCD jl loc_50720D
CODE:00506FD3 lea edx, [ebp+var_1C]
CODE:00506FD6 mov eax, offset a65537 ; "65537"
CODE:00506FDB call @Base10StringToFGInt
CODE:00506FE0 xor eax, eax
CODE:00506FE2 push ebp
CODE:00506FE3 push offset loc_507206
CODE:00506FE8 push dword ptr fs:[eax]
CODE:00506FEB mov fs:[eax], esp
CODE:00506FEE lea edx, [ebp+var_8]
CODE:00506FF1 mov eax, offset aC5e974ffb63d4a ; "C5E974FFB63D4A3B7717D9CC07AFD194B0B6003"...
CODE:00506FF6 call @ConvertHexStringToBase256String
CODE:00506FFB lea edx, [ebp+var_24]
CODE:00506FFE mov eax, [ebp+var_8]
CODE:00507001 call @Base256StringToFGInt
CODE:00507006 xor eax, eax
CODE:00507008 push ebp
CODE:00507009 push offset loc_5071E9
CODE:0050700E push dword ptr fs:[eax]
CODE:00507011 mov fs:[eax], esp
CODE:00507014 lea eax, [ebp+var_8]
CODE:00507017 call System::__linkproc__ LStrClr(System::AnsiString &
CODE:0050701C lea edx, [ebp+var_8]
CODE:0050701F mov eax, [ebp+var_4]
CODE:00507022 call @ConvertBase64to256

xybyre
March 12th, 2003, 22:48
Solomon,

I've been using NetCaptor since version 6.x, and my latest version was 7.0.1. 7.0.1 didn't have those new tricks in it. It just displayed the dialog from the timer function, and I was able to pause it and look down the call stack (or pRet) to find the calling function.

Thank you for pointing out that UPX command. I still have much to learn about packers (can't you tell? ), so I needed the practice.

That info about the RSA implementation will come in handy as well, but how did you know it used RSA for key validation? Is it just a part of your routine to search for it?

My real concern was whether it was possible to track down those protection routines without the help of a disassembler. What can I do in this situation if I don't have IDA handy? The stack doesn't show the calling functions.

Solomon
March 12th, 2003, 23:47
I got the same problem(no call stack etc.) when I first tried to crack it(v7.0bx or so).

It displays error NAGs in a new thread, not new process(Do u agree?). So if we trace back, we will land at the end of this thread then get lost. With SoftICE only, it's also easy to find where the new thread is created, e.g where the hidden check/jump is. Let me explain.

Finally I find out that all hidden checks have sth. to do with the Registered_or_Not flag just as you have got.

if (Registered_or_Not == 0)
{
This is evaluation version.
CheckSystemDateTime( );
if (expired version) Registered_or_Not = 1;
}

if (Registered_or_Not == 2)
{
This is registered version, now do some hidden checks here.
}

so set a BPM on this flag, we will find almost all the hidden checks. Also we can search for this flag in W32Dasm dead-listing if we don't want to limit ourselves to debuggers only.
Code:

CODE:004F209D mov byte ptr [esi], 0 <--Evaluation Init
CODE:004F20A0 xor eax, eax
CODE:004F20A2 mov [esi+4], eax
CODE:004F20A5 call sub_506F54 <----key validation
CODE:004F20AA mov al, [esi]
CODE:004F20B1 cmp al, 2 <------registered ver?
CODE:004F20B3 jz short loc_4F2132
CODE:004F20B5 lea eax, [ebp+var_C]
CODE:004F20B8 call sub_4D5B5C <------check sys date/time
CODE:004F20BD mov eax, [ebp+var_C]
CODE:004F20C0 mov [esi+4], eax
CODE:004F20C3 cmp eax, 0Fh <------15-day limit hit?
CODE:004F20C6 jle short loc_4F20CB
CODE:004F20C8 mov byte ptr [esi], 1 <-------expired version


The size check can be found by "BPX FindFirstFileA". Many Delphi/BCB appz use this API(wrapped by TSearchRec) to get file size, instead of GetFileSize etc. Such as CommView, YATS32......(perhaps Alexy told them to do so )
Code:

CODE:004ED36D add esp, 0FFFFFFF8h
CODE:004ED370 mov ebx, eax
CODE:004ED372 mov eax, ebx
CODE:004ED374 call sub_4EDC94
CODE:004ED379 mov eax, esp
CODE:004ED37B call sub_4D5B5C
CODE:004ED380 call sub_48EE44
CODE:004ED385 cmp eax, 0C3500h <--------size check

Solomon
March 13th, 2003, 02:07
here I attach the FGInt.sig for any one who doesn't want to install big Delphi to compile FGint.pas then get a sig file.

xybyre
March 13th, 2003, 10:51
I believe the older versions displayed the nags in a separate thread, but this new version definitely creates a new process to do it. I used OllyDbg and when the nag popped up, I'd switch to OllyDbg and see "Terminated" in the status bar.

Code:
004F065C runNetCaptorNag proc near ; DATA XREF: sub_4F0640+1o
004F065C
...
004F0696 call getExeFilename
004F069B lea eax, [ebp+var_4]
004F069E mov edx, offset aBoing ; " --boing"
004F06A3 call @@LStrCat ; __linkproc__ LStrCat
004F06A8 mov eax, [ebp+var_4]
004F06AB call @@LStrToPChar ; __linkproc__ LStrToPChar
004F06B0 push eax
004F06B1 call j_WinExec ; runs "NetCaptor.exe --boing"
004F06B6 mov eax, ebx
004F06B8 call terminateApp
If I run "NetCaptor --boing" from the command prompt, I see the nag.

Solomon
March 13th, 2003, 20:18
yes, you are right. I'm wrong about this for the new version.

Quote:
Originally posted by xybyre
I believe the older versions displayed the nags in a separate thread, but this new version definitely creates a new process to do it. I used OllyDbg and when the nag popped up, I'd switch to OllyDbg and see "Terminated" in the status bar.