HOWBIE TO WRITTING A PLUGIN'S OLLY 1.10
Author: Benina (REA) 2007
Part 1 : Hello World
Từ trước đến giờ chưa thấy bài nào nói về vấn đề này trên net để chỉ cho newbie chúng ta viết một plugin cho Olly yêu dấu. Mà cũng vì hôm bữa offline, các staff của REA tâm sự muốn phát triển REA giống như các nhóm khác. Tức là anh em ta phải codding các tool tự xài cho nó pro. Chứ xài đồ chùa hòai cũng thấy ái nái.
Hôm nay tôi mạo muội viết về đề tài này để anh em ta cùng nhau nâng cao trình độ. Dĩ nhiên là vạn sự khởi đầu nan. Lúc đầu thì thấy nó khó nhưng từ từ rồi ta cũng quen và coding good hơn. Chủ yếu là kiên nhẩn. Mặt khác tôi lại thấy olly ra cái ver 2.0 beta mới toanh, mình lại viết cho thằng nhà wê 1.10 thấy cũng ngại. Sợ viết xong thì ko có giá trị sử dụng nhiều. Nhưng kệ chắc nó cũng giá trị phần nào vì dù sao ông Olly cũng nâng cấp chút ít thôi. Hy vọng thế.
Xin các bạn nhớ rằng, tôi trong REA là newbie nhất vì ko học hành gì về IT. Chỉ ngâm cứu cho vui thôi. Nên các bạn đừng ngại học cái này khó. Benina mà làm được thì ông nào newbie nhất cũng có thể làm được.
Lại spam tiếp chút, ai cũng wen codding theo một ngôn ngữ mình chọn. Nhưng ở đây tôi chỉ thảo luận về masm32, vì thấy các reverser cao thủ trên thế giới ai cũng biết về masm32. Mặc dù họ ko code thường xuyên. Nhưng nói một reverser mà ko biết asm thì kỳ dị. Còn code bằng masm32 thì ko ai thèm code. Vì sao chắc khỏi giải thích. Nên mình viết tut dùng ngôn ngữ lập trình bằng masm32 thì chắc ai nghiên cứu reverse cũng hiểu.
Ok, spam đủ rồi, gogogo
Yêu cầu:
-Biết code chút đỉnh về masm32. Xem các bài tut tôi đã posted.
-Trước khi đọc bài này, các bạn nếu chưa bao giờ code một DLL thì đọc bài tut 17 của Iczelion tôi đã tranz rồi hả đọc tut này.
-Một chút kiên nhẩn
Ý chính:
-Ta cần hai files: plugin.inc và ollydbg.lib for masm (bạn tìm trên mạng nhé, đầy)
-Một DLL ta cần xem đầu tiên là nó export ra các hàm nào.
Olly định nghĩa các hàm mà một plugin của nó sẽ export là :
EXPORTS
_ODBG_Plugindata
_ODBG_Plugininit
_ODBG_Pluginmenu
_ODBG_Pluginaction
_ODBG_Plugincmd
_ODBG_Pluginreset
_ODBG_Plugindestroy
..v..v...
File .def có dạng sau:
LIBRARY nameplugin
EXPORTS
_ODBG_Plugindata
_ODBG_Plugininit
_ODBG_Pluginmenu
_ODBG_Pluginaction
_ODBG_Plugincmd
_ODBG_Pluginreset
_ODBG_Plugindestroy
Tùy theo ta dùng hàm nào thì ta export hàm đó.
Chi tiết viết plugin:
1. Nhân của một DLL
Nhân của một DLL phải có hàm DllEntryPoint. Olly sẽ load plugin ngay từ khi startup.
Vì vậy ta dùng DLL_PROCESS_ATTACH.
.386
.model flat, stdcall
option casemap:none
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\ollydbg.lib
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\plugin.inc
include Strings.mac
;**************************************************************************************
.data
;**************************************************************************************
;**************************************************************************************
.data?
hinst HINSTANCE ?
;**************************************************************************************
;**************************************************************************************
.code
DllEntryPoint proc hi:HINSTANCE, reason:dword, res:dword
.IF reason == DLL_PROCESS_ATTACH
m2m hinst, hi
.ENDIF
return 1
DllEntryPoint endp
;**************************************************************************************
end DllEntryPoint
; DllEntryPoint là entry point của một DLL. Nhiều hàm gọi của system yêu cầu DLL instance
; mà nó được truyền đến DllEntryPoint() như là một trong những tham số parameters.
2.Phần bắt buộc của Olly đối với một plugin
Olly bắt buộc một plugin phải có hai hàm có tên ODBG_Plugindata và ODBG_Plugininit.
; Hảy ghi nhớ điều này:
; Cách hay dùng là để đặt các khởi trị đầu (biến) trong hàm ODBG_Plugininit() và
; cleanup (xóa nó) trong ODBG_Plugindestroy().
a/ ODBG_Plugindata:
; ODBG_Plugindata() phải có để OllyDbg plugin được hợp lệ theo quy ước của Olly. Nó phải được “lắp” vào
; tên plugin name và giá trị trả về là version of plugin interface. Nếu hàm này ko có,
; hay ver là ko tương đương, thì plugin sẽ ko được installed. Biến shortname
; chỉ định nó (plugin) trong Plugins menu. Tên này có chiều dài max là 31 ký tự alphabe
; và một ký tự '\0' kết thúc. Để dễ dàng cho người dùng,
; tên này nên mô tả chức năng của plugin và đúng với tên of DLL.
;**************************************************************************************
ODBG_Plugindata proc C shortname:ptr byte
invoke lstrcpy, \
shortname, \
$CTA0("BePlus\:")
return PLUGIN_VERSION
ODBG_Plugindata endp
;**************************************************************************************
Ở đây hàm này chỉ có động tác là copy tên mà user dùng để đặt cho plugin vào biến shortname.
giá trị trả về trong eax là ver của plugin Olly
b/ ODBG_Plugininit:
; OllyDbg gọi hàm bắt buộc này trong suốt quá trình startup. Hảy đặt tất cả các khởi trị đầu
; tại đây. Nếu tất cả các “tài nguyên” khởi trị đầu được cấp phép thành công thì,
; function phải return 0. Nếu có lỗi error, nó phải free các “tài nguyên” cấp phép ko hòan chỉnh và
; trả về return -1, trong cas này plugin sẽ bị removed. Tham số ollydbgversion
; là version of OllyDbg, sử dụng nó để đảm bảo tương thích với plugin của bạn
; hw là handle of main OllyDbg window, lưu giữ nó cần thiết sử dụng sau này.
; Các tham số đặc biệt này được lưu giữ cho các phần mở rộng sau này của plugin, đừng dùng nó.
;**************************************************************************************
ODBG_Plugininit proc C ollydbgversion:dword, hw:HWND, features:ptr dword
.IF ollydbgversion < PLUGIN_VERSION
jmp _bad_exit
.ENDIF
invoke Addtolist, \
0, \
0, \
$CTA0("BePlus\: v1.0")
invoke Addtolist, \
0, \
-1, \
$CTA0(" Copyright (C) 2005 by Benina")
m2m hwmain, hw
return 0
_bad_exit:
return -1
ODBG_Plugininit endp
;**************************************************************************************
3.Thêm tên plugin vào menu chính của Olly.
Để cho người dùng tiện sử dụng các tính năng mà plugin chúng ta mang lại, chúng ta phải add vào menu chính của Olly một item cho plugin chúng ta.
Ta dùng hàm ODBG_Pluginmenu.
Hàm này làm cho plugin có khả năng add items menu hoặc là vào menu chính của Olly hoặc là lọai menu xổ ra popup trong standard OllyDbg windows. Hàm này được định nghĩa như sau:
int ODBG_Pluginmenu(int origin,char data[4096],void *item);
origin là code của window gọi ODBG_Pluginmenu. PM_MAIN là code của main window olly gọi hàm.
data là con trỏ đến buffer chứa chuổi mô tả cấu trúc menu
;**************************************************************************************
ODBG_Pluginmenu proc C origin:dword, data:ptr byte, item:dword
.IF origin == PM_MAIN
invoke lstrcpy, \
data, \
$CTA0("0 &fBenina |1 &About")
return 1
.ENDIF
return 0
ODBG_Pluginmenu endp
;**************************************************************************************
Cách viết chuổi ("0 &fBenina |1 &About") như thế nào, đề nghị tham khảo thêm trong phần hướng dẫn viết plugin của Olly
4.Code hành động của plugin.
; Hàm này nhận các commands từ plugin menu trong window of type
; origin. Đối số action là menu identifier từ ODBG_Pluginmenu(). Nếu user
; kích hoạt một cách tự động thành phần đã cài đặt trong main menu,thì action là 0.
;**************************************************************************************
ODBG_Pluginaction proc C origin:dword, action:dword, item:dword
.IF origin == PM_MAIN
.IF action == 0
invoke MessageBox, \
hwmain, \
$CTA0("BePlus\: plugin v1.0\nCopyright (C) 2007 by Benina is newbie"),\
$CTA0("BePlus\:"), \
MB_OK or MB_ICONINFORMATION
.ELSEIF action == 1
invoke MessageBox, \
hwmain, \
$CTA0("BePlus\: plugin v1.0\nCopyright (C) 2007 by Benina"),\
$CTA0("BePlus\:"), \
MB_OK or MB_ICONINFORMATION
.ENDIF
.ENDIF
ret
ODBG_Pluginaction endp
;**************************************************************************************
5.Ví dụ:
Đây là ví dụ hoàn chỉnh:
.386
.model flat, stdcall
option casemap:none
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\ollydbg.lib
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\plugin.inc
include Strings.mac
GetParamFromCmd proto cmd:ptr char, param_num:dword ; returns parameter from cmd:
; EAX = t_result.u
; ESI > ASCIIZ param
;**************************************************************************************
.data
;**************************************************************************************
;**************************************************************************************
.data?
hwmain dd ?
hinst HINSTANCE ?
;**************************************************************************************
;**************************************************************************************
.code
DllEntryPoint proc hi:HINSTANCE, reason:dword, res:dword
.IF reason == DLL_PROCESS_ATTACH
m2m hinst, hi
.ENDIF
return 1
DllEntryPoint endp
;**************************************************************************************
;**************************************************************************************
ODBG_Plugindata proc C shortname:ptr byte
invoke lstrcpy, \
shortname, \
$CTA0("BePlus\:")
return PLUGIN_VERSION
ODBG_Plugindata endp
;**************************************************************************************
;**************************************************************************************
ODBG_Plugininit proc C ollydbgversion:dword, hw:HWND, features:ptr dword
.IF ollydbgversion < PLUGIN_VERSION
jmp _bad_exit
.ENDIF
invoke Addtolist, \
0, \
0, \
$CTA0("BePlus\: v1.0")
invoke Addtolist, \
0, \
-1, \
$CTA0(" Copyright (C) 2005 by Benina")
m2m hwmain, hw
return 0
_bad_exit:
return -1
ODBG_Plugininit endp
;**************************************************************************************
;**************************************************************************************
ODBG_Pluginmenu proc C origin:dword, data:ptr byte, item:dword
.IF origin == PM_MAIN
invoke lstrcpy, \
data, \
$CTA0("0 &fBenina |1 &About")
return 1
.ENDIF
return 0
ODBG_Pluginmenu endp
;**************************************************************************************
;**************************************************************************************
ODBG_Pluginaction proc C origin:dword, action:dword, item:dword
.IF origin == PM_MAIN
.IF action == 0
; ShowOptionsWindow
invoke MessageBox, \
hwmain, \
$CTA0("BePlus\: plugin v1.0\nCopyright (C) 2007 by Benina is newbie"),\
$CTA0("BePlus\:"), \
MB_OK or MB_ICONINFORMATION
.ELSEIF action == 1
invoke MessageBox, \
hwmain, \
$CTA0("BePlus\: plugin v1.0\nCopyright (C) 2007 by Benina"),\
$CTA0("BePlus\:"), \
MB_OK or MB_ICONINFORMATION
.ENDIF
.ENDIF
ret
ODBG_Pluginaction endp
;**************************************************************************************
end DllEntryPoint
6. Biên dịch:
-Copy file plugin.lib vào thư mục lib của masm32
-Copy file plugin.inc vào thư mục include của masm32
-Tạo thư mục BePlus : c:\masm32\BePlus
-Tạo file BePlugs.def:
LIBRARY CLBPlus!
EXPORTS
_ODBG_Plugininit
_ODBG_Plugindata
_ODBG_Pluginaction
_ODBG_Pluginmenu
-Tạo file make.bat
if exist BePlus.dll del BePlus.dll
\masm32\bin\ml /c /coff /Cp BePlus.asm
\masm32\bin\Link /SUBSYSTEM:WINDOWS /DLL /DEF:BePlus.def BePlus.obj
del BePlus.obj
del BePlus.exp
del BePlus.lib
pause
-Chạy file bat