ACDSee 3.1 build 808

Written by anTiHerO



ACDSee is several tools in one. A full-featured image Viewer quickly generates a high quality display of your image. The image Browser lets you efficiently find and organize your images. ACDSee also provides several image manipulation functions, including a convenient Photo Enhancer.


Tools required




Debugger (Softice or TRW2000)

Half a brain


Target's URL




Let's get started! This essay is in two parts. The first part concentrates on manually unpacking the executable, and the second part on removing the Nag / Time Limit protection.


If we try to run our target using the softice loader, we will notice that softice never breaks....hmmmm. Me thinks we have a protected .exe, which becomes even more evident if we try to disassemble our target with W32Dasm, only to find that it crashes. Lets try ProcDump!

Open ProcDump , hit the PE Editor button, and it will prompt you to select the exe, select acdsee.exe and hit open, and you will be greeted by the PE Structure Editor. On the left, you should see the windows, containing Entry Point, Image Size, and Image Base . WRITE THESE VALUES DOWN! Next, click on the sections button, and you should see a section in the window called .aspack . Problem found! ASPack seems to be quite a good exe protector, but once you know how, it is fairly easy to get around! hehe.

I am not going into the ins-and-outs of why I am doing certain things, if you really need to know, check out Volatilities essay on manual unpacking ASPack, you should know where to find it! OK, lets carry on.

In the ProcDump window showing the .aspack data. The top section should be .text. Right click on the .text and select Edit Section from the menu. We need to change the section characteristics from:






Click OK! Quit ProcDump and load our target into softice, run it, and BANG! up pops our softice window! This is because when we changed the section characteristics, it is now telling softice that it contains read/write code, and it will break when executed.

In the softice window, we are inside the packers code, and you will see the following code ( after a bit of tracing);

55B277	XOR	EBX, EBX		
55B279	OR	ECX, ECX		
55B27B	JZ	0055B2AB		
55B27D	JS	0055B2AB		
55B27F	LODSB			
55B280	CMP	AL, E8		
55B282	JZ	0055B28E		
55B284	JMP	0055B286		
55B286	CMP	AL, E9		
55B288	JZ	0055B28E		
55B28B	DEC	ECX		
55B28C	JMP	0055B279		This starts huge loop, STOP!
55B28E	MOV 	EAX, [ESI]		Set a bpx on this location
We want to be at the location after the jmp, so we need to set a break point on the next line, so in softice type;
bpx 55B28E
and then hit Ctrl+D, and you will be on the MOV statement, a bit more tracing, and you should end up;
55B2CC	PUSH	00008000				
55B2D1	PUSH	00				
55B2D3	PUSH	DWORD PTR [EBP + 4439E1]				
55B2D9	CALL	[EBP + 4439ED]				
55B2DF	ADD	ESI, 08				
55B2E2	CMP	DWORD PTR [ESI], 00				
55B2E5	JNZ	0055B211				This starts another loop, STOP!
55B2EB	PUSH	00008000				Set a bpx on this location.
Can you see whats happening here? 
The code keeps putting us into huge loops that would take a day to trace through, so we need to set a bpx on the next location (0055B2EB);
A bit more tracing;
55B4B7	JUMP	0055B504				
55B4B9	MOV	[EDI], EAX				
55B4BB	ADD	DWORD PTR [EBP + 004439DD]				
55B4C2	JMP	0055B3F9				Starts the loop! STOP!
55B4C7	MOV	[ESI], EAX				Set a bpx on this location
A bit more tracing;
55B4CC	MOV	[ESI + 10], EAX				
55B4CF	ADD	ESI, 14				
55B4D2	MOV	EDX, [EBP + 0044478C]				
55B4D8	JMP	0055B3C8			        Start of loop! STOP!	
55B4DD	MOV	EAX, [EBP + 00443A02]		  Set a bpx here	
A bit more tracing;
55B4F3	POPAD					
55B4F4	JNZ	0055B4FE				
55B4F6	MOV	EAX, 00000001				
55B4FB	RET	000C				
55B4FE	PUSH	004ACA0E		                Write this location down! (004ACA0E)		
55B503	RET			                      This is the end of our protection code		
Just one thing! Dont forget to clear the breakpoint after each break!
The next thing we need to do is make a dump of the program code. To do this, we must make the packer code loop indefinately. We can do this by changing the ret at 
55B503 into a jump. So with the ret highlighted in softice, type;
 a eip (enter)
then type;
  jmp eip (enter)(enter)
Press Ctrl+D to exit softice, and the program will be looping on itself, so start up ProcDump and locate our ACDSee.exe in the Tasks window. Right-click and choose Dump (Full)
You will then be prompted to name the dumped file, just called it dumped.exe or similar and hit OK. File Dumped!
If you try to run our freshly dumped exe, it doesnt work! This is because we still need to change the file header to our new entry point. 
The location we should have written down just before the RET instruction is the Original Entry Point (OEP), which we need to change to
our new entry point (missing the packer code). We do this by using ProcDump, so fire it up!
Click on the PE Editor button and select our dumped executable, hit OK. Again we see our Entry Point, Image Size, and Image Base values.
We need to change the original entry point to our new entry point, which we can work out;
New Entry Point = Original Entry Point - Image Base
Remember that the OEP is the location we noted before the final RET in the packer code, which works out as;
New Entry Point = 004ACA0E - 00400000 = 000ACA0E
Change the Entry Point box in ProcDump to 000ACA0E, click OK, and double click on our dumped exe. IT WORKS!!! First part done!
We can now set about removing that nag screen and time limit. I used softice to find the point at which the nag is called, but you can disassemble the unpacked exe if you wish (I used it for reference!).
Load up our unpacked exe with the softice symbol loader and when softice breaks, trace with F10 until we are in the program code. We now want to be writing down which calls pop up the nag screen
and step into each one until we can't go any further. This will mean you will have to go through the code a few times, but we will get there in the end!
So, when softice first breaks, trace with F10 until we get here;
4ACAE2	CALL	004D7498		
4ACAE9	CALL	004BC300		The nag is called here, F8 into the CALL
4ACAEE	MOV	[EBP - 60]		
Once you have stepped into this CALL, trace some more with F10, until you hit;
4BC308	PUSH	DWORD PTR [ESP + 10]			
4BC310	CALL	004C3FB8			This calls the nag, F8 into the CALL
4BC315	RET	0010			
Once inside the CALL, trace some more;
4C3FF6	JZ	004C4021			
4C3FF8	MOV	EAX, [ESI]			
4C3FFC	CALL	[EAX + 50]			This calls the nag, F8 into it
When in the CALL, get to this point;
404B7C 	PUSH	EBP			
404B7D	CALL	004BEBD4			
404B82	CALL	004044B0			The nag is called here, F8 into it
404B87	TEST	EAX, EAX			
Nearly there!	
404596	CALL	DWORD PTR [004D7254]				
40459C	TEST	EAX, EAX				
40459E	JG	004045B6				What do we have here?
4045A0	MOV	ECX, DWORD PTR [004D71B0]				
4045A6	PUSH	00000000				
4045A8	CALL	DWORD PTR [004D7264]			This calls the nag!
4045AE	TEST	EAX, EAX				
If we trace into the CALL at 4045A8, we are greeted by nothing but a RET, so we must have reached the end of the line! If we look just above this call
we see a conditional jump at 40459E that NEVER jumps! Hmmmm, what if we FORCED it to jump past the CALL at 4045A8 so that the nag is never called! If we 
trace through code so that the conditional jump at 40459E is highlighted and type;
a (enter)
then type;
jmp 004045B6 (enter) (enter)
you should see that the command has changed to an unconditonal jump (JMP) that will take us past the nag call, so Ctrl+D
and we are past the CALL that pops the nag, so Ctrl+D again.........Straight into the program!!!!!
Now we can use our hex editor to permanently change the conditional jump into an unconditional jump (use our Disassembled listing to get the correct
hex offset). JOB DONE!!!! Our job is made a bit easier because the time limit is removed as well as the nag. So once we have patched our code and restart
the program, we never see the nag, and the program never expires!
The title bar in our program still says Trial, but I will leave it up to you to remove that, as I think this essay is long enough already!


Final Notes

Pat yourself on the back, grab a beer and a cigar, and relax, safe in the knowledge that you just learnt something usefull!!


My Greetz Goes to:

[T]urb0z – For introducing me to these infernal machines

The TRES2000 Crew
My mum

When ever there is a door,
there is an entrance.
And behind an entrance can no secret hide,
when a cracker takes his knowledge for a ride



The information in this essay is for educational purpose only!
You are only allow to crack, reverse engineer, modify code and debugg programs that you legaly bought and then for personal use only!!
To ignore this warning is a criminell act and can result in lawful actions!

So please note!
I take no responebility for how you use the information in this essay, i take NO responebility for what might happen to you or your computer!
You use this information on your own risk!!

What i mean is: Please buy the software!

Essay written by anTiHerO ©TRES2000. All Rights Reserved.