Message Hooking Utilizing ctypes

Taking Advantage of Win32 APIs in Python

To take advantage of the powerful features provided by the Windows operating system in Python, it is necessary to use the Win32 API. Python version 2.7 provides the basic ctypes module that allow us to take advantage of the variables of C language and the DLLs.

Python Using an External Library

At first, when you use the Win32 API and the ctypes, it may be slightly difficult to use Win32 API calls by using the ctypes. There is an extensive amount of knowledge that is necessary in advance, such as the function call mechnism, return values, and data types. However, the ctypes can be used for native libraries that are supported by a variety of operating systems, which provides a powerful tool. To implement sophisticated hacking techniques, the basic concept of the ctypes should be understood. The ctypes are like a MacGyver knife in that they support a variety of platforms including Android, Windows, Linux, Unix, and OS X. These are very useful tools, like a Swiss Army Knife.

The Basic Concept of the ctypes Module

The ctypes simplify the procedure to make dynamic libraries calls, and these support complex C data types and have the advantage of providing low-level functionality. If you follow the conventions to call functions to take advantage of the ctypes, you can call the API that is provided directly by MSDN.

Concept of the ctypes

Native libraries and Python have different function call methods and data types, and therefore you must learn the basic ctypes grammar that is used to accurately perform mutual mapping.

Let's examine the basic concept of ctypes from the criteria of Windows.

DLL Loading

- The ctypes supports a variety of calling conventions.

The ctypes supports cdll, windll, and oldell calling convention. cdll supports the cdecl calling convention. windll supports the stdcall calling convention. oldell supports the same calling convention as windll, but there is a point to assume a return value as an HRESULT.

windll.kernel32, windll.user32

Win32 API Call

- Put the name of the function that you want to call after the DLL name.

windll.user32.SetWindowsHookExA

- When the API is called, it is possible to specify the type of arguments.

printf = libc.printf

printf.argtypes = [c_char_p, c_char_p, c_int, c_double]

printf("String '%s', Int %d, Double %f\n", "Hi", 10, 2.2)

- It is possible to specify the type of return value for the function.

libc.strchr.restype = c_char_p

Data Type

- Python can use the data type of the C language by using the data types provided by the ctypes module.

In order to use the integer type of C, it is using the ctypes as follows.

   i = c_int(42)

   print i.value()

- You can use a pointer to store an address.

PI = POINTER(c_int)

Delivery of a pointer

- You can pass a pointer (the address of the value) as an argument to the function.

f = c_float()

s = create_string_buffer('\000' * 32)

windll.msvcrt.sscanf("1 3.14 Hello", "%f %s", byref(f), s)

Callback Functioin

- You can declare and pass a callback function that is responsible to process specific events.

def py_cmp_func(a, b):

print "py_cmp_func", a, b

return 0

CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))

cmp_func = CMPFUNC(py_cmp_func)

windll.msvcrt.qsort(ia, len(ia), sizeof(c_int), cmp_func)

Structure

- By inheriting the Structure class, you can declare the structure class.

class POINT(Structure):     #선언

_fields_ = [("x", c_int), ("y", c_int)]

point = POINT(10, 20)      #사용

 

In many cases, you must pass the arguments when calling the Win32 API. If you want to directly transfer the data that is used in Python, the Win32 API cannot recognize the data correctly. The ctypes provide a “cast function” to solve these problems, and the “cast function” changes the variable types used in Python into variable types used in the Win32 API. For example, we need a float pointer as an argument when calling the “sscanf” function, and when you cast a variable into the “c_float” type provided by ctypes, you can call the function correctly. The mapping table is as follows.

ctypes type

C type

Python type

c_char

char

1-character string

c_wchar

wchar_t

1-character unicode string

c_byte

char

int/long

c_ubyte

unsigned char

int/long

c_short

short

int/long

c_ushort

unsigned short

int/long

c_int

int

int/long

c_uint

unsigned int

int/long

c_long

long

int/long

c_ulong

unsigned long

int/long

c_longlong

__int64 or long long

int/long

c_ulonglong

unsigned __int64 or
unsigned long long

int/long

c_float

float

float

c_double

double

float

c_char_p

char * (NUL terminated)

string or None

c_wchar_p

wchar_t * (NUL terminated)

unicode or None

c_void_p

void *

int/long or None

Variable Type Mapping Table

Now, with the basic concept of the ctypes module in hand, let's create full-fledged hacking code. For message hooking, you should first understand the hook mechanism, and you need to understand the Win32 APIs that are required for hacking.

Post a Comment

Previous Post Next Post