Sent Rev
Sent Rev
�� ____ __ __ ����
�� / _/_ _ __ _ ___ ____/ /____ _/ / �� ���
�� _/ // ' \/ ' \/ _ \/ __/ __/ _ `/ / �� � �
�� /___/_/_/_/_/_/_/\___/_/ \__/\_,_/_/ �� � �
�� ____ __ __ �� � �
�� / __ \___ ___ _______ ___ ___/ /__ ____ / /____ �� � �
�� / /_/ / -_|_-</ __/ -_) _ \/ _ / _ `/ _ \/ __(_-< �� � �
�� /_____/\__/___/\__/\__/_//_/\_,_/\_,_/_//_/\__/___/ �� � �
�� �� � �
�� Web: http://www.immortaldescendants.org �� � �
�� EFnet: #immortaldescendants �� � �
�� Author: Muad'Dib [ muaddib@immortaldescendants.org ] �� � �
�� Topic: Securing Sentry �� � �
�� Date: 4/18/2000 �� � �
�� Level: �� � �
�� ( ) Beginner (X) Intermediate (X) Advanced ( ) Expert �� � �
�� �� � �
����������������������������������������������������������������� � �
�������������������������������������������������������������������
���������������������������������������������������������������
�����������������������������������������������������������������������������
�����������������������������������������������������������������������������
The long awaited tutorial is finally here! Come one come all
to watch the splendor we call REVERSING!
Tools needed:
SoftICE
IDA or W32DASM (I use IDA)
HIEW or Hex Workshop (I used both for some reason :)
OPGen
Procdump
Here goes:
Enter your sentry password and enable it. You will get a message
saying "Sentry lockdown has been enabled". Disable it and then
disassemble sentry. Search for the string that says sentry has
been enabled.
We get this:
.text:00403115 6A 30 push 30h
.text:00403117 68 04 B5 40 00 push offset aTheSentry_0; "The Sentr
.text:0040311C 68 10 B6 40 00 push offset aTheSentryHasNo; "The Se
.text:00403121 FF B4 24 4C 03 00 00 push dword ptr [esp+34Ch]
.text:00403128 FF 15 1C 92 40 00 call ds:MessageBoxA
DWORD GetPrivateProfileString(
Looking at the code, EBP contains our password. Now lets overwrite
the push that comes after GetPrivateProfileStringA because we can always
put that back later.
Now comes Procdump. Open up sentry.exe with Procdump and click the
"sections" button. The raw offset is 1000 and the size is 784A. Open
sentry.exe in your hex editor and go to the offset 884A (1000 + 784A).
Well would you look at that, we have a bunch of null bytes! Go to the
offset 2F34 (402F34 - 400000). Now it's time for Opgen. Opgen will
generate a jump for you. Since the end of the code is 884A, we want
to jump from 2F34 to 884A. Opgen gives us this:
E9 11 59 00 00
But first we want to note down the old opcode so we can add it again:
FF 35 44 C1 40 00
Since the new opcode is 1 byte less than the old one we add a nop at the
end:
E9 11 59 00 00 90
Now we need to make a stupid little encryption code that is strong enough
to keep our little sisters and our mothers out.
.386
code32 segment para public use32
assume cs:code32,ds:code32
org 100h
main:
pushad
looper:
mov al,byte ptr [ebp]
cmp al,0
je endit
xor al,'�' ; (238)
mov byte ptr [ebp],al
inc ebp
jmp looper
endit:
popad
code32 ends
end main
C:\id\projects\sentry>tasm stupid.asm
Turbo Assembler Version 4.1 Copyright (c) 1988, 1996 Borland International
C:\id\projects\sentry>tlink /t stupid.obj
Turbo Link Version 7.1.30.1. Copyright (c) 1987, 1996 Borland International
And open the file in your hex editor. You will get the following bytes
of code:
60 8A 45 00 3C 00 74 0C 90 90 90 90-34 8C 88 45 00 45 EB ED 61
FF 35 44 C1 40 00
E9 D0 A6 FF FF
Well, now that we've got this done, the rest should be easy. The
next name checking portion uses the exact same code so lets overwrite
the push again and use the almost the exact same bit of code.
E9 82 56 00 00 90
60 8A 45 00 3C ... etc
E9 5F A9 FF FF
That's that. Now we have to edit the password changing portion (don't
worry, we're almost done ;). Search for "Sentry password has been" in
your disassembly and you come up with this:
So the password is stored in 40CAE0 and then put into EDI. Looks like we
will have to overwrite "mov edi, offset unk_0_40CAE0". We can always
replace it at the memory location our code jumps to. So we need to jump
from 20C9 to 888A:
E9 BC 67 00 00
Remember to write down the old opcode for the mov so we can replace it. Now
put the old opcode in starting at 888A.
.386
code32 segment para public use32
assume cs:code32,ds:code32
org 100h
main:
pushad
looper:
mov al,byte ptr [edi]
cmp al,0
je endit
xor al,'�' ; (238)
mov byte ptr [edi],al
inc edi
jmp looper
endit:
popad
code32 ends
end main
60 8A 07 3C 00 74 0B 90 90 90 90 34 8C 88 07 47 EB EF 61
Got it? Good job. Now once again lets jump back to the old location
(88A2 to 20CE):
E9 27 98 FF FF
BOOL WritePrivateProfileString(
Looks like EAX is the password. Time to modify the code again:
.386
code32 segment para public use32
assume cs:code32,ds:code32
org 100h
main:
pushad
looper:
mov al,byte ptr [eax]
cmp bl,0
je endit
xor bl,'�' ; (238)
mov byte ptr [eax],bl
inc eax
jmp looper
endit:
popad
code32 ends
end main
This time we have to use "BL" as the byte register that holds the letter
being changed because EAX is being taken by the name. Compile it and get
this:
60 8A 18 80 FB 00 74 0C 90 90 90 90-80 F3 8C 88 18 40 EB ED 61
E9 01 69 00 00 90
We do the nop because the call is 1 byte longer than the jump. Make sure you
wrote down the opcode for calling WritePrivateProfileStringA.
Just add our encryption code and then jump back from 88C2 to 1FA7:
E9 E0 96 FF FF
That's it! We're done! Just a bit of janitorial work to do. Erase the file
c:\windows\system\qtime20.dat and then open up your modified sentry. Set a
new password and then test everything out! It all works!
Enjoy!
Very special thanks go out to Carpathia for helping me when I was a wee
reverser! Thanks to Volatility for being a good friend and a great leader!
Thanks to NeuRaL_NoiSE for making OPGen and thanks to G-RoM, Lorian, and
Stone for Procdump, another excellent tool!
-Muad'Dib