Thứ Tư, 3 tháng 4, 2013

The Hacker’s Best Friend: ctypes

Python module ctypes là một trong các powerful libraries có sẵn cho Python developer. ctypes library cho phép ta gọi các functions trong các thư viện liên kết động DLL và có khả năng mở rộng cho việc tạo các kiểu dữ liệu C phức tạp và các functions tiện ích cho việc thao tác low-level memory.

Using Dynamic Libraries

Bước đầu tiên trong việc tận dụng ctypes là làm thế nào để giải  quyết và truy nhập đến các functions in DLL. DLL là là một compiled binary, được liên kết lúc runtime đến process executable chính. Trên Windows nhiều binary được gọi là DLL, trong khi đó trên Linux chúng được gọi là shared objects (SO). Trong cả hai trường hợp, các binaries sẽ phô ra các functions thông qua exported names, những gì giải quyết với các địa chỉ thực sự trong memory. Thông thường at runtime bạn phải resolve các function addresses theo thứ tự để gọi các functions; Tuy nhiên, với ctypes tất cả các dirty work đã được hoàn thành.

Có 3 cách khác nhau để load dynamic libraries trong ctypes: cdll(), windll(), oledll(). Sự khác nhau giữa 3 cách trên nằm ở cách các functions trong libraries được gọi và kết quả của chúng trả lại giá trị. cdll() method được sử dụng cho việc loading libraries mà export functions sử dụng quy ước chuẩn cdecl. windll() sử dụng stdcall  những gì là quy ước của MS Win32 API, oledll() được tổ chức giống như windll(), tuy nhiên nó được giả sử exported functions trả lại HRESULT  error code, những gì được dành riêng cho error messages trả lại tư MS Component Object Model (COM) functions.

UNDERSTANDING CALLING CONVENTIONS

calling convention mô tả cách làm thế nào một cách hợp lí để gọi một hàm. Nó bao gồm thứ tự: làm thế nào function parameters được cấp phát, những parameters được pushed trên stack hoặc được passed trong registers và làm thế nào stack được unwound khi fuction return. Ta cần hiểu 2 calling conventions đó là : cdecl stdcall . Trong cdel parameters được pushed từ phải sang trái và caller của function chịu trách nhiệm cho clearing các arguments từ stack. Nó được sử dụng bởi hầu hết C systems trên x86.

Chúng ta xét 2 ví dụ để minh họa:

Ví dụ 1: cedl function call
In C
                     int python_rocks(reason_one, reason_two, reason_three)
In x86 Assembly
                     push reason_three
                     push reason_two
                     push reason_one
                     call python_rocks
                     add esp, 12

Các bạn có thể nhận thấy rằng các arguments được passed từ phải qua trái và dòng cuối cùng tăng stack pointer lên 12 bytes (có 3 parameters đến function, và mỗi stack parameter là 4 bytes, do đó 12 bytes), những gì về bản chất clear  các parameters.

Ví dụ 2: stdcall convention, được sử dụng trong Win 32 API
In C
                    int my_socks(color_one, color_two, color_three);
In x86 Assembly
                    push color_three
                    push color_two
                    push color_one
                    call my_socks

Trong trường hợp này ta có thể thấy thứ tự passed các parameters là giống nhau, nhưng stack clearing không được thực hiện bởi caller; my_socks function chịu trách nhiệm cho việc cleaning up trước khi nó return.

Đối với cả 2 conventions điều quan trọng để note là return values được lưu trong thanh ghi EAX.




Không có nhận xét nào:

Đăng nhận xét