12/2005 by Zadig.
Tools needed:
Introduction:
To use Zeta R1 you have to register your copy to yellowtab. If you do not, a nag
application reminds you that you must do it. You have several ways to register
but you will most probably end up by using internet since it is the most
convenient solution.
We can understand that yellowtab wants to ensure that people really bought there
copy but it can also be a good way for them to get information from users. In
this document I will present an analyse of the registration process to see what
is really doing Zeta, and what kind of information it sends to yellowtab. We
will then see if it is possible to register a copy legally without network
connection. This may be usefull if you use like me a test install that is often
deleted/reinstalled.
I- The registration process in Zeta R1.
II- The registration process in Zeta R1 SP1.
III- Registering without network.
Just after Zeta's installation you are asked to register you copy. The application that asks for it let you choose between two ways of doing this: If you have an internet connection you just have to enter your serial number and activation key, and let the process goes on through internet. If you do not have an internet connection must must either send a mail to yellowtab, either phone them so that you get 2 activation codes. If you do not register, this application will appear periodically.
"activate" is the application that asks for the serial number. It is located at "/boot/beos/bin/" (or /bin this is the same). After disassembling it we find one interesting class:
Class BRegistration 0000FA54: BRegistration::BRegistration(void) 0000FACC: BRegistration::Init(void) 0000FAD4: BRegistration::Invoke(void) 0000FAE8: BRegistration::IsRegistered(void) 00010174: BRegistration::Perform(int, int) 0000FB28: BRegistration::Register(char const *, long, long) 0000FADC: BRegistration::ShowRegisterWindow(void) 0000FA88: BRegistration::~BRegistration(void)Let's first look at the "IsRegistered" method. There is almost nothing in it. This function is entirely based on a call to "BApplication::Perform(0x4d6, 0)". This function is in libbe.so. The "0x4d6" message is handled at the begining of the function. Here is the partial call graph of this function:
+BApplication::Perform(unsigned long, void *)
+_BAppServerLink_::_BAppServerLink_(void)
+_BAppServerLink_::Init(bool)
+BApplication::connect_to_app_server(void)
+BPrivate::AppSession::swrite(long, void const *)
+BPrivate::AppSession::flush(void)
+BPrivate::AppSession::sread(long, void *)
+_BAppServerLink_::~_BAppServerLink_(void)
We see here that we connect the the app_server, send datas and read datas. So it
is the app server that tells if we are registered or not. Thus we will have a
deeper look at it but later. For now we will continue to see what is happening in
"activate". The other interesting method of BRegistration is "Register".
Its 3 parameters are the serial number and the 2 activation codes. Looking at this function's dead-listing you can guess that there are important things in it because the strings contruction is more or less obfuscated. In fact this function is just adding attributes to some files:
listattr /boot/beos/apps/People | grep code listattr /boot/beos/system/servers/app_server | grep code listattr /boot/beos/system/kernel_intel | grep sserSo registering your copy of Zeta is just adding an attribute to 3 files. There are several important things that all users should be aware of:
Now we know what is done to set your install as registered but not how we get the activation codes. The "Register" method is called at two places:
So the only personnal information that is sent to yellowtab is your ip address. This is both few and a lot of information since several insteresting things can be extracted from it. When you bought your copy they had a link between the serial number and a name/address. With the registration process they also have a link with an ip adress.
Know that we saw what is doing "activate" let's see what is in the app server. As we saw previously, "activate" uses the app server to know if Zeta is registered. So let's look at its disassembly, and the class list:
Class BRegistration 0008F4E4: BRegistration::BRegistration(void) 0008F5A0: BRegistration::Init(void) 0008F5D0: BRegistration::Invoke(void) 0008F7A4: BRegistration::IsRegistered(void) 00090694: BRegistration::Perform(int, int) 0009003C: BRegistration::Register(char const *, long, long) 0008F5FC: BRegistration::ShowRegisterWindow(void) 0008F558: BRegistration::~BRegistration(void)These are exactly the same methods than on the activate application. However we will see that the code of the IsRegistered method is quite different. Still looking at interesting functions we can see this:
00079C40: TServer::RegistrationLaunch(TServer *) 00079B64: TServer::RegistrationThread(void)Let's first look at the "TServer::RegistrationThread(void)" method. It consists of a loop that checks if Zeta is registered:
while(1)
{
snooze();
if(b_IsRegistered == false)
BRegistration::Perform();
if(BRegistration::IsRegistered == false)
{
BRegistration::Perform();
BRegistration::Invoke();
b_Isregistered = true;
}
}
This is not the exact code but it represents more or less what is done in it. We
see that the "b_IsRegistered" flag is cached in memory, probably to avoid disks
accesses once the thread knows that we are registered. Now let's look at the
different functions. "BRegistration::Invoke" just calls
"ShowRegisterWindow", "ShowRegisterWindow" tries to launch
"/boot/beos/bin/activate". If the activate application could not
be lauched, "/boot/beos/bin/reinstallactivate.sh" is executed. This script just
shows a modal alert that invite you to insert Zeta's install cd and then copies
"activate" where it should be. But what is happening if "reinstallactivate" is
also missing ? In fact this is not tested. The app_server assumes that it
exists and then calls "ShowRegisterWindow" again. Thus you can see that we
should end up in an infinite loop if both "activate" and "reinstallactivate" are
missing (however I did not try it).
Finally the "IsRegistered" method is in some way the most interesting one since it extracts the 2 activation codes of the serial number to check that the 3 file attributes are correct. I will not give details on this here since it is not the purpose of this text. I will just say that the serial number is hashed to extract these two codes.
Now we have a global view of the registration process. The different parts of it are shown below:
______________________________________
| |
| app_server |
|______________________________________|
| /|\ | |
| | | |
|starts |IsResigtered | |
| |(libbe.so) | |
_\|/________|____ | |
| | | |
| activate | | |
|_________________| | |
| | | |
| |wr attr |rd attr |
| | | |
__\|/___ _\|/__________\|/___ \|/________
| | |Filesystem: | | |
| notice | |- app_server | | reinstall |
|________| |- kernel_intel | |___________|
|- People |
|____________________|
Now let's see what has changed in the service pack 1. At first I did not intend to present this but I was quite forced to do it. When I started to study the registration I had Zeta R1 installed. I then installed SP1 before having finished to study all parts because I did not thought that the app_server would have changed (big mistake from me!). So I used the old app_server dead-listing and debugged the new one... and I saw very strange things. I almost got headakes until I realized that the binary had changed, and especially the registration part.
The binary has changed but it seems that the registration part has not changed at all. By the way the code size of the new version (.text section) is only bigger of 48 bytes from the old one. So almost nothing changed here.
As I said previously the app server has evolved. In fact I saw this when I
removed both "activate" and "reinstallactivate" to check that there was an
infinite loop. A big surprise appeared: There was no infinite loop but the
activation app was started! nethertheless "/bin/activate" was not there. So how
could it be executed ? After a little search you can see that it exists in the
"/tmp" directory.
I spent a lot of time to find where this came from because I used the old
dead-listing. At one time I also thought that the "activate" app was crypted
somewhere before being flush on "/tmp", and that the app server was patched at
runtime to do this! But in fact things are much simple when you use the correct
disassembly.
What has changed here is the "ShowRegisterWindow" method. Now it does the
following things:
So now the global view of the registration process is:
________________________________________________________
| |
|__________ app_server |
| activate | |
| zipped | __________ |
|__________|_|__________|________________________________|
| | | | /|\ |
|copy |unzip | | | |
| | | |starts |IsResigtered |
| | | | |(libbe.so) |
__\|/_______|__ _\|/__\|/_______|_____ |
| | | | |
| /tmp/filexxxx | | /tmp/activate | |
|_______________| |______________________| |
| | |
| |wr attr |rd attr
| | |
__\|/___ _\|/_________\|/____
| | |Filesystem: |
| notice | |- app_server |
|________| |- kernel_intel |
|- People |
|____________________|
Now that we know exactly how is done the registration we can see how to register it when you do not have an internet connection.
Before the SP1 there was a very easy way to use Zeta without registering it: You
just had to replace the "activate" binary with an empty script. So the file
exists, it is executed, but does nothing. However by doing this your copy
is never considered as registered by the app server and it will do disk
accesses regularily. I suppose that the app server changed in SP1 to avoid this
trick.
However there is still a way to do this easily in SP1. But since this is just a
quick and dirty hack I will not detail it here.
The first elegant solution that I thought about was using a fake registration server. We have all necessary apps with Zeta to do it. The issue with it is that the "register.php" script must send back the 2 activation codes. I first thought that these keys were computed by the app server and that the php script just had to return "ok". If it was true then we would just have to:
If you already have your activation codes, there is obviously a very simple way to register Zeta: Adding the correct attributes to the correct files will just do what "activate" is doing. This can be done with this shell script:
#!/bin/env sh rmattr code12 /boot/beos/apps/People rmattr code24 /boot/beos/system/servers/app_server rmattr sser1762 /boot/beos/system/kernel_intel addattr -t int32 code12 your-activation-code1 /boot/beos/apps/People addattr -t int32 code24 your-activation-code2 /boot/beos/system/servers/app_server addattr -t string sser1762 your-serial-number /boot/beos/system/kernel_intelThe problem here is that you must at least register once to yellowtab to get the activation codes.
Finally there is a last solution to reinstall Zeta without having to register: Once you are registered, just backup your installed copy on a cd and do your next installs from this cd. The new installs will be already registered.
As we saw yellowtab is only sending the minimum necessary information through internet to register a copy. So it seems that this is not a way to spy users. But I am not convinced that this is usefull anyway: When you buy your copy the registration process could have been done locally. We can imagine that if someone releases a cracked version of Zeta he would anyway remove all registration information in it (unless he is really stupid or stoled his copy to somebody).
This network registration may be usefull for yellowtab to see how many times a user installs its copy. I did not see on how many machines they allow to install Zeta with one license. I assume that if they see 60 registration requests for one serial number, they will send a little mail to this user.
I will finish with the most important thing in my opinion: Never send you kernel
file as is to anybody. I know that it could seem strange to do such a thing but
I did received a lot of these files when we worked on the xp patch and the 1Gb
memory patch for R5. So this may occur sometime.
Zadig.