Trao đổi với tôi


[Reverse's Tools] .NET Reflector 7 (beta) EAP

鈥� Better decompilation, including iterator block (yield) support, and improved .NET 4.0 support.
鈥� Tabbed decompilation.
鈥� The ability to decompile and explore code in referenced assemblies directly in Visual Studio.

There are also numerous bug fixes and smaller improvements.

System requirements are still pretty modest, although you will need .NET 3.5 or later to run this new version of Reflector. Other than that, Windows XP or later, 128 MB of RAM (although we鈥檇 recommend more), and 16 MB free hard disk space, is where it鈥檚 at.

NOTE: This is pre-release software, which may be unstable. Use at your own risk. Each EA build will expire every couple of weeks or so. When that happens, co

download from official site (the right red ribbon)

[Reverse's Tools] NirLauncher v1.10.13

NirLauncher v1.10.13


joeware free tools package:

SysInternals Suite package:

Translation Packs:

[Reverse's Tools] P32Dasm

Christmas gift for you :-)
This release improves analyzing VB native code applications. Don't ask for plugin because it's property of some Slovak AV company. More about plugin + screens on main site.

2.7 - [04.12.2010] - "Another start" Release
+ Added support for IDA Visual Basic Debugger plugin (source export)
+ Added "Heurestic assign unknown procedures into objects" (not all but it helps a lot of in native code apps!)
+ Adding VB5 SubMain to list of procedures if it's missing in list
+ Added parameters to some opcodes
* Fixed Drag & Drop files into P32Dasm

Home + Screen (mirror)

Download (mirror)

(main site can't be updated now)



[Reverse's Tools] Tools collection

Nothing special. Just large tools collection on single DVD (from a few sources).

Cracking Kit 2010+ (DVD ISO)

Brief (directories list):

> Aids
> Analyzers
> Archiver
> Bin
> Calc
> Catalog
> Cleanup
> Comparision
> Converters
> Crack Me
> CRC & Hash
> Crypto
> Debuggers & Disassemblers
> DLLs
> Dongles and LMs
> Editors
> Encryptors
> EXE Tools
> File
> Hack
> Hex Editors & Viewers
> Hooking
> Install
> ListGrabbers
> Loaders
> Math
> Mix Utils
> Monitors
> Organizer
> Packers
> Password Crackers
> Patchers
> PE & Dumpers
> Printer
> Registry
> Resources
> Rich
> Security
> Snapshots
> Timing
> Unpacking & Cracking
> Viewers

ck2010+.part01.rar (476,8 MB)

ck2010+.part02.rar (476,8 MB)

ck2010+.part03.rar (476,8 MB)

ck2010+.part04.rar (476,8 MB)

ck2010+.part05.rar (476,8 MB)

ck2010+.part06.rar (476,8 MB)

ck2010+.part07.rar (476,8 MB)

ck2010+.part08.rar (476,8 MB)

ck2010+.part09.rar (476,8 MB)

ck2010+.part10.rar (281,6 MB)

Psw: RbySxkNWBzdGPXCF4xCY8fe4


[Net] Những nguyên tắc chung khi cài đặt modem ADSL Wireless

Những nguyên tắc chung khi cài đặt modem ADSL Wireless


[Source] Tools and proof-of-concept codes

DISCLAIMER: All the tools in this section should be considered as proof-of-concepts tools. They are provided with the hope that they might be useful for other researches. They are not intended to be used by 'end users'. There is no support. Keep in mind that some of these tools may crash your system without a single warning! USE AT YOUR OWN RISK!

The Blue Pill Project

I wrote the original Blue Pill proof of concept code while working for COSEINC back in 2006, and presented it at the Black Hat Briefings 2006 in Las Vegas on August 3rd. In April 2007 I decided to quit COSEINC and start my own security consulting firm, Invisible Things Lab. In May 2007 Alexander Tereshkin, a former member of COSEINC AML, joined ITL as a principal researcher. Together with Alex we decided to redesign and write from scratch the New Blue Pill rootkit, so that it would be possible to use it for further research and for educational purposes. Most of the New Blue Pill’s code was developed by Alexander Tereshkin. You can get the sources from the project's website.

System Virginity Verifier

The idea behind SVV is to check important Windows System components, which are usually altered by various stealth malware, in order to ensure system integrity and to discovery potential system compromise.

See my HITB and Black Hat presentations (links below) for more details about design and usage.


modGREPER is a hidden module detector for Windows 2000/XP/2003. It searches through kernel memory in order to find structures which looks like a valid module description objects.

FLISTER proof-of-concept

FLISTER is a proof-of-concept code for detecting files hidden by both usermode and kernelmode Windows rootkits. It exploits the bugs (usually made by rootkit authors) in handling ZwQueryDirectoryFile() calls with ReturnSingleEntry set to TRUE. flister works on Windows 2000, XP and 2003.

NUSHU - passive covert channel engine for Linux 2.4 kernels

NUSHU is the sample implementation of TCP ISN based passive covert channel for Linux kernels, which I presented at 21st CCC in Berlin in 2004. It should be considered as proof-of-concept code, since it is only the communication channel engine.

[Hooking] uallCollection

(c) by uall

You can download the collection here and some examples here. (Update 07.07.06)

Your are not allowed to use the collection or parts od it inside any comercial product without my permission.

[Hooking] Hook detection

1.madShow tool:

Hi, I am writing a small programm which displays all current installed user hooks. I've create msall support for madCHook, maybe someone can test it, and say if it works. Thx

HookShark BETA 0.9 (with a vengeance)

It has been one month only, and here i come with another big update.
And yes, it's worth it.

I am doing a quick overview of what has changed.

I am introducing the first tool that detects Hooks of VTables.
It does so by tracing certain assembly patterns and relocated blocks in the data section, that might be a table of virtual method-pointers.

If you set the verbosity high HookShark will also list all changed relocated function ptrs. in data sections.

Also all found global instances of polymorphic classes with VTables are listed in one section for your convinience to ease the analysis of your target.

So feel free to test around some stuff. HookShark might not find all virtual function tables. But this is hardly avoidable.

Resigzed ImageClick this bar to view the full image.

Next up is the new built-in Disassembler. Not much functionality. Just to grant a quick look at the area, if this is something worth exploring further with a debugger.

Some targets might fuck with us, guarding pages or even the modulelists. Also time-attacks to detect thread suspensions is a common technique.
So if the target crashes on scan or doesn't seem to be scannable, play around with the new Troubleshooting options in the Global Options Tab.

Also check out the new Credits Dialog. I included the old Chiptune, that you might know from 0.6.

Abso insisted on testing out the new bug-tracking system. So if you want to report bugs, then try it out:

I don't know if i will use it. But it doesn't hurt to check it put. If you want to be extra sure, mention the bug here in this thread.

Resigzed ImageClick this bar to view the full image.

PS: Yeah i know. The pictures show version "0.8" :P
That's because im lazy to make new pictures.


Fixed version:


09-02-2010 - 1 -- Fixed memory leak. Thx to MiDoX



[Rootkit] WinDbg Cheat Sheet

Everyone ends up creating their own Windbg cheat sheet to help them along as learn Windbg. I have found others sheets very helpful as i went so here are the notes i have compiled.

The Windbg UI can include many different dockable windows. You can also open multiple ones of the same type (I like to keep multiple memory windows open so I can chase down pointers and see things in different formats). Getting a Window configuration and layout you are comfortable and efficient with can take a bit of fussing (luckily windbg saves your layout across runs). Here is what I have found comfortable for me.

When you set breakpoints, you can include commands to be executed I often find it helpful to add a label like

bp 0x41414141 ".echo in function x"

You can also have analyze data for you. Here are some useful breakpoints that analyze arguments

bp nt!ZwCreateFile "du poi(poi(esp+10)+0xC);g" bp kernel32!LoadLibraryExA "da poi(esp+4);g" bp kernel32!LoadLibraryExW "du poi(esp+4);g" bp kernel32!LoadLibraryA "da poi(esp+4);g" bp DbgPrint "da poi(esp+4)" bp nt!zwopenfile "du poi(poi(esp+10)+0xC)" 
You can also set conditional break points

bp 41414141 "j @eax=0xbaadf00d \;g\"

which means "break at address 41414141 if eax = 0xbaadf00d else go"

One shot breakpoints can be set with

bp 0x41414141 /1

You can also set breakpoints inside of loops and set them to only break after being hit x times.

bp 0x41414141 x

You can also set memory access breakpoints. The format is ba (break access) [op][size] where op is operation (rwe) and size is length to trigger on. I think size must be aligned to a 4 byte boundry. if 4 fails use 1

ba w4 41414141 ba r1 41414141 
To edit a byte in memory: (change value at addr 41414141 to 55 (push ebp))

eb 0x41414141 55

If you want to manually change eip an address you desire:

r @eip=0x41414141

You can dump memory to disk using the .writemem command. You can either dump a range with two addresses as the arguments, or you can specify a start address and a length to dump by length. You can also add a ? to the length specifier to bypass length checks.

.writemem c:\hostmachine\range.bin 0x0400000 0x0404000 .writemem c:\hostmachine\length.bin 00400000 L4000 .writemem c:\hostmachine\length.bin 00400000 L?4000 
The kernel includes a table of function pointers like the import address table does in a user mode app. Its called the KiServiceTable and you can view it in memory by entering its symbol address in a memory window and viewing the data as pointer and symbol mode.

nt!KiServiceTable 804742b8 8049dd52 nt!NtAcceptConnectPort 804742bc 804af6c1 nt!NtAccessCheck 804742c0 804b043a nt!NtAccessCheckAndAuditAlarm 804742c4 8050d5b8 nt!NtAccessCheckByType 804742c8 804b0470 nt!NtAccessCheckByTypeAndAuditAlarm ... 
To get a dump of a driver table you can use the drvobj command. it has allot of useful info on function pointers and events it implements. This info is not available at very early stages of system loading though. table has to be initilized first.

!drvobj atapi 2 2

If you want to see which modules are loaded you can use the lm command.

To see the entire device node tree, you can use the following command:

!devnode 0 1

If you want to start teh debugger at a very very early stage of system startup you can install a debug boot loader from the relevant ddk. (ntldr_dbg) This will let you break before even the OS selection prompt shows up and when only osloader.exe is loaded. For more details check out this helpful article Windows Boot Debugger If you want to break early in teh boot, but not necessarily boot loader early, you can request to stop at the initial breakpoint by going to

Debug->Kernel Connection -> Cycle Initial Break (or hitting ctrl+alt+K and rebooting)

You can reboot the target machine by issuing a .reboot command.

You can also have Windbg break on many different events such as new process, or thread module loading etc. Check out the event filters dialog.

To set breakpoints in user mode sections of memory you have to be in teh correct process. You will have to Changing Context and then reload your symbols.

During kernel-mode debugging, you can set the process context by using the .process (Set Process Context) command. Use this command to select which processs page directory is used to interpret virtual addresses. After you set the process context, you can use this context in any command that takes addresses. You can even set breakpoints at this address. By including a /i option in the .process command to specify invasive debugging, you can also use the kernel debugger to set breakpoints in user space.

You can also set user-mode breakpoints from the kernel debugger by using a process-specific breakpoint on a kernel-space function. Set strategic breakpoints and wait for the appropriate context to come up.

With WinDBG, another thing you can do is use !bpid to have the kernel debugger break into the context of the process you e interested in and then you can set your breakpoints in the user-mode code (after running .reload to reload your symbols).

For example, setting a breakpoint in CreateFileW in a process:

0: kd> !process 0 0 **** NT ACTIVE PROCESS DUMP **** .... PROCESS 861c9d90 SessionId: 1 Cid: 0f10 Peb: 7ffd3000 ParentCid: 0b48 DirBase: 0174e2a0 ObjectTable: 96f14eb0 HandleCount: 5. Image: testapp.exe 1: kd> .process /r /p 861c9d90 Implicit process is now 861c9d90 ..cache forcedecodeuser done Loading User Symbols 

Another interesting article from MS Controlling the User-Mode Debugger from the Kernel Debugger


[Reverse] PDF Stream Dumper

This is a free tool for the analysis of malicious PDF documents. It also has some features that can make it useful for pdf vulnerability development.

Has specialized tools for dealing with obsfuscated javascript, low level pdf headers and objects, and shellcode. In terms of shellcode analysis, it has an integrated interface for libemu sctest, an updated build of iDefense sclog, and a shellcode_2_exe feature.

Javascript tools include integration with JS Beautifier for code formatting, the ability to run portions of the script live for live deobsfuscation, toolbox classes to handle extra canned functionality, as well as a pretty stable refactoring engine that will parse a script and replace all the screwy random function and variable names with logical sanitized versions for readability.

Tool also supports unescaping/formatting manipulated pdf headers, as well as being able to decode filter chains (multiple filters applied to the same stream object.)

Download: PDF Stream Dumper Setup 0.9.148 (includes full vb6 source)

Training videos for PDFStreamDumper:If you are looking for malicious pdf samples to analyze make sure to check out the Contagio and jsunpack sites.

International users: This new build should now work on systems with extended character set languages set as their default language. If you encounter errors please let me know.

Full feature list
  • supported filters: FlateDecode, RunLengthDecode, ASCIIHEXDecode, ASCII85Decode, LZWDecode
  • Integrated shellcode tools:
    • sclog gui (Shellcode Analysis tool I wrote at iDefense)
    • scTest gui libemu based Shellcode analysis tool
    • Shellcode_2_Exe functionality
    • Export unescaped bytes to file
  • supports filter chaining (ie multiple filters applied to same stream)
  • supports unescaping encoded pdf headers
  • scriptable interface to process multiple files and generate reports
  • view all pdf objects
  • view deflated streams
  • view stream details such as file offsets, header, etc
  • save raw and deflated data
  • search streams for strings
  • scan for functions which contain pdf exploits (dumb scan)
  • format javascript using js beautifier (see credits in readme)
  • view streams as hex dumps
  • zlib compress/decompress arbitrary files
  • replace/update pdf streams with your own data
  • basic javascript interface so you can run parts of embedded scripts
  • PdfDecryptor w/source - uses iTextSharp and requires .Net Framework 2.0
  • Basic Javascript de-obsfuscator
  • can hide: header only streams, duplicate streams, selected streams
  • js ui also has access to a toolbox class to
    • simplify fragmented strings
    • read/write files
    • do hexdumps
    • do unicode safe unescapes
    • disassembler engine
Current Automation scripts include:
  • csv_stats.vbs - Builds csv file with results from lower status bar for all files in a directory
  • pdfbox_extract.vbs - use pdfbox to extract all images and text from current file
  • string_scan.vbs - scan all decompressed streams in all files in a directory for a string you enter
  • unsupported_filters.vbs - scan a directory and build list of all pdfs which have unsupported filters
  • filter_chains.vbs - recursivly scans parent dir for pdfs that use multiple encoding filters on a stream.
  • obsfuscated_headers.vbs - recursivly scans parent dir for pdfs that have obsfuscated object headers
  • pdfbox_extract_text_page_by_page.vbs - uses pdfbox to extract page data into individual files

Current Plugins include:
  • Build_DB.dll
  • obj_browser.dll

Credits: --------------------------- stream parser was written by VBboy136 - 12/9/2008  JS Beautify by Einar Lielmanis, _ conversion to Javascript code by Vital,  zlib.dll by Jean-loup Gailly and Mark Adler  CRC32 code by Steve McMahon  iTextSharp code by Bruno Lowagie and Paulo Soares  olly.dll GPL code Copyright (C) 2001 Oleh Yuschuk.  libemu and sctest.exe written by Paul Baecher and Markus Koetter 2007.   sclog is a tool i wrote back at iDefense source here   Interface by  Other thanks to Didier Stevens for the info on his blog on tags and encodings.  

[System Info] What is the SDT Cleaner?

SDT Cleaner is a tool that intends to clean the SSDT (system service descriptor table) from hooks.

  • The SDT Cleaner allows you to clean hooks installed by Anti-Virus and Firewalls.
  • This little tool (in this first release) tries to collect info from your current kernel and then switches to kernel land and if there are any hooks in SSDT, this tool will replace them with the original entries.


  • In this first release, you'll just need Windows XP.
  • I'm planning to add support for Windows 2000 / 2003.

Binaries and Source Code


  • SDT Cleaner is distributed under a slightly modified version of the Apache Software License. Feel free to review it here and compare it to the official Apache Software License.

Known Issues

The following features are not working yet.

  • Running in VMware.
  • Clean hooks from functions.
  • Windows 2000 / 2003 / 2008 / Vista Support.

Contact Us

Whether you want to report a bug, send a patch or give some suggestions on this package, drop us a few lines at oss@. To contact me, Nahuel C. Riva, the author, you can reach me at nriva@ .


SDT Cleaner
Release date
License type
Apache 1.1

Attachments - sdt cleaner v1

[Reverse] What is turbodiff?

What is turbodiff?

Turbodiff is a binary diffing tool developed as an IDA plugin. It discovers and analyzes differences between the functions of two binaries.


Turbodiff works with IDA versions 4.9 and 5.x.


For the binaries:
Download the plugin and store it at the directory "..\IDA\plugins".

If you want to compile it on your own: We have compiled it and tested it using Borland C. For the free version of IDA Pro (4.9) you'll need to first:
1. Generate the ida_free.lib library. To do this execute:
"implib -c ida_free.lib ida_free.def"
2. Next, you must have the linker use this library.
3. Compile.

Comparing two files:

  1. Open the first file to be compared with IDA and run /Option 1 (take info from this idb)/ from the plugin. Close.
  2. Open the second file to be compared with IDA and run /Option 1 (take info from this idb)/ from the plugin.
  3. Use /Option 2 (compare with...)/ from the plugin, and when prompted to select a file, select the first file. Chose if you want a log file to be genreated and run. Once finished a functions table will popup (watch Figure 1) describuing results. The results are then saved for later usage.

Accessing a comparison generated earlier:

  1. Open one of the files with IDA. Select /Option 3 ("Compare functions with...")/ from the plugin options and choose the other file to be compared. The table will popup without executing any new tasks.

Comparing any two functions:

  1. After comparing two files, you can compare any two functions between each by using /Option 4 ("Free comparison with...")/ and specifying the addresses of these actions.

Understanding the Output

The table

Each row represents two funct5ions that are being compared, and with 5 columns, category, address, name, address, name, where category describes the relationship between two functions, the 2nd and 3rd column describe address/name for the first function and the 4th and 5th columns describe address/name for the second function being compared.
The categories can be:

  • identical:
    • Same function graph;
    • Same checksum in each basic block;
    • Same amount of instructions in each basic block;
  • suspicious+:
    • Same function graph;
    • /Different/ checksum in each basic block;
    • Same amount of instructions in each basic block;
  • suspicious++:
    • Same function graph;
    • /Different/ checksum in at least one basic block;
    • /Different/ amount of instructions in at least one basic block;
  • changed:
    • None of the above;
    • Related by an heuristic, as described in the presentation;
  • unmatched:
    • None of the above;

Colors for basic blocks when diffing functions

  • white: Same checksum and number of instructions
  • green: Same number of instructions

  • yellow: Different number of instructions

  • red: Basic block that the differ didn't match.


Known Issues

  • There is an issue to be solved with the heuristics that produces false negatives when detecting identical functions. This will be solved by the next release.


This software is provided under the GPLv2 license.

Contact Us

Whether you want to report a bug or give some suggestions on this package, drop us a few lines at oss- at or contact the author, Nicolas Economou, at neconomou@


Release date
License type
GPL v2.


[MASM] Calling functions without importing them

I started off writing this as an add-on to my PE Infection post. However, I think it's turned into a big enough project that it deserves it's own thread lol. The original idea was to have a stub for my PE infecter that could call any API it wanted *without* using fixed addresses. Using fixed Addresses makes the resulting stub version-dependant, which is lame.

Anyways, the way this works is pretty simple. It starts off by finding the base address of kernel32.dll (by using the Process Environment Block), and then it parses kernel32.dll's exports and looks for the two functions LoadLibraryA() and GetProcAddress(). From there, any WinAPI function is within arms reach.

Implementing this was another story. The only part that really needed to be in asm was the part that found kernel32.dll, but I chose to write it all in asm. The biggest thing that screwed me up was converting RVAs to plain old VAs. For a while I didn't realize that it was as trivial as adding the RVA to the actual base address, so I ended up writing a function that scanned every section in the PE file and returned the offset the RVA would have in a file. Once I got rid of this, the rest came quickly. :-)


; ------------------------------------------------
; call.asm - finds kernel32.dll in memory and
; searches it's export table for LoadLibraryA()
; and GetProcAddress(). From there, calling
; functions that haven't been imported is trivial.
; :-)
; Assembled with:
; nasm call.asm -fwin32 -o call.obj
; gcc call.obj -o call.exe
; AdhesiveBall - August/2010
; ------------------------------------------------

[BITS 32]
global _WinMain@16

section .data
WorkedMessage db "Hello from an unimported function!", 0

LoadLibraryName db "LoadLibraryA", 0
LoadLibraryAddr dd 0xFFFFFFFF

GetProcAddressName db "GetProcAddress", 0
GetProcAddressAddr dd 0xFFFFFFFF

MessageBoxName db "MessageBoxA", 0
MessageBoxAddr dd 0xFFFFFFFF

User32Name db "user32.dll", 0
User32Addr db 0xFFFFFFFF

Kernel32Addr dd 0xFFFFFFFF

section .text

; -----------------------------------------------
; void *FindKernel32Base(void)
; tries to find the base address of kernel32.dll
; returns NULL on error
; -----------------------------------------------
mov eax, [fs:0x30] ; address of PEB
mov eax, [eax + 0x0C] ; PEB->Ldr
mov eax, [eax + 0x1C] ; Ldr->InMemoryOrderModuleList (first element is ntdll.dll)
mov eax, [eax] ; InMemoryOrderModuleList->Flink (second element is kernel32.dll)
mov eax, [eax + 0x08] ; DllBase
cmp word [eax], 'MZ' ; check for MZ header
je FindKernel32Base_end
xor eax, eax ; zero eax if not found

; ------------------------------------------------------
; void *LoadFunction(HMODULE module, char *FunctionName)
; attempts to find the address of function by
; walking module's Export Address Table
; ------------------------------------------------------
push ebp
mov ebp, esp
sub esp, 12 ; make room for 3 DWORDS

; look at my stack frame, my stack frame's amazing
; +-----------------------+
; ebp-0x0C | PE Header |
; +-----------------------+
; ebp-0x08 | Export table addr |
; +-----------------------+
; ebp-0x04 | AddressOfNames |
; +-----------------------+
; .....
; +-----------------------+
; ebp+0x08 | kernel32 base address |
; +-----------------------+
; ebp+0x0C | function name |
; +-----------------------+

mov edi, [ebp + 0x08] ; edi = DosHeader

; -------------------------
; verify MZ and PE headers
; -------------------------
cmp word [edi], 'MZ'
jne LoadK32Function_fail
mov edx, edi
add edx, [edi + 0x3C] ; module + DosHeader->e_lfanew (edx = PeHeader)
cmp word [edx], 'PE'
jne LoadK32Function_fail
mov [ebp - 0x0C], edx ; save the PE header

; ------------------------------
; find the real addr of the EAT
; ------------------------------
mov eax, [edx + 0x78] ; OptionalHeader.DataDirectory[0].VirtualAddress
add eax, dword [ebp + 0x08] ; add the offset to the base address
mov [ebp - 0x08], eax ; save it!

; ----------------------------------------
; find the real address of export names
; ----------------------------------------
mov eax, [eax + 0x20] ; eax is still addr of EAT (0x20 = offset to ADdressOfNames)
add eax, dword [ebp + 0x08]
mov [ebp - 0x04], eax

; --------------------------------
; start looking for names!
; --------------------------------
xor ecx, ecx
mov edx, [ebp - 0x08] ; EAT
cmp ecx, [edx + 0x18] ; NumberOfNames
jge LoadK32Function_fail

; --------------------------------------
; find the address of the function name
; --------------------------------------
mov ebx, [ebp - 0x04] ; AddressOfNames
mov ebx, [ebx + ecx * 4] ; RVA of string
add ebx, [ebp + 0x08]

; compare 'em!
push dword [ebp + 0x0C] ; FunctionName
push ebx ; name of entry
call strcmp
cmp eax, 1
je LoadK32Function_found_api

inc ecx
jmp LoadK32Function_loop_names

; success! now all that's left is to go from the
; AddressOfNames index to the AddressOfFunctions index
; -----------------------------------------------------

; First thing's first, find the AddressOfNameOrdinals address
mov eax, [ebp - 0x08]
mov eax, [eax + 0x24] ; AddressOfNameOrdinals offset
add eax, [ebp + 0x08]

; Now we gotta look up the ordinal corresponding to our api
xor ebx, ebx
mov bx, [eax + ecx * 2] ; ecx * 2 because it's an array of WORDS

; Next we find the AddressOfFunctions array
mov eax, [ebp - 0x08]
mov eax, [eax + 0x1C] ; AddressOfFunctions offset
add eax, [ebp + 0x08]

; and last we find the address of our api!
mov eax, [eax + ebx * 4]
add eax, [ebp + 0x08]

jmp LoadK32Function_end
xor eax, eax
mov esp, ebp
pop ebp
ret 8

; -------------------------------------------------------------
; unsigned int RVAToFileOffset(
; IMAGE_NT_HEADERS *ntHeader, unsigned long virtualAddr);
; Converts a relative virtual address to an offset in the file
; -------------------------------------------------------------
; push ebx
; mov eax, [esp + 0x08] ; eax = ntHeader
; mov ebx, [esp + 0x0C] ; ebx = virtualAddr
; push ecx
; push edx
; xor ecx, ecx
; mov cx, [eax + 0x06] ; ecx = number of sections
; lea edx, [eax + 0xF8] ; edx = first section
; RvaToFileOffset_loop_sections:
; push ecx ; used as a temporary variable throughout the loop
; ; -------------------------------------------------------------
; ; check if the virtual address resides in the current function
; ; -------------------------------------------------------------
; cmp ebx, [edx + 0x0C] ; if(virtualAddr <>VirtualAddress) continue;
; jl RvaToFileOffset_continue
; mov ecx, [edx + 0x0C]
; add ecx, [edx + 0x08] ; ecx = section->VirtualAddress + section->VirtualSize
; cmp ebx, ecx ; if(virtualAddr >= ecx) continue;
; jge RvaToFileOffset_continue
; RvaToFileOffset_DEBUGLABEL:
; ; -------------------
; ; Success! It's here
; ; -------------------
; sub ebx, [edx + 0x0C] ; find the offset from the beginning of the section's virtual addr
; add ebx, [edx + 0x14] ; add it to the PointerToRawData member
; jmp RvaToFileOffset_success
;; RvaToFileOffset_continue:
; add edx, 0x28 ; edx += sizeof(IMAGE_SECTION_HEADER)
; pop ecx ; restore for use as a counter
; loop RvaToFileOffset_loop_sections
; xor eax, eax ; baww
; jmp RvaToFileOffset_end
; pop ecx ; ecx will be on the stack 'coz of the loop so we need to fix it
; mov eax, ebx
; pop edx
; pop ecx
; pop ebx
; ret 8

; -------------------------------------------------
; int strcmp(char *a, char *b)
; returns 1 if the two strings are equal, 0 if not
; -------------------------------------------------
push ebx
mov eax, [esp + 0x08]
mov al, byte [eax]
mov ebx, [esp + 0x0C]
cmp al, byte [ebx]
jne strcmp_not_equal
cmp al, 0
je strcmp_equal
inc dword [esp + 0x0C]
inc dword [esp + 0x08]
jmp strcmp_loop

mov eax, 0
jmp strcmp_end

mov eax, 1

pop ebx
ret 8

; -----------------------------------------------
; kinda bloated but meh does it's job
call FindKernel32Base
cmp eax, 0
je _WinMain_failed
mov [Kernel32Addr], eax

; find LoadLibrary()
push LoadLibraryName
push dword [Kernel32Addr]
call LoadK32Function
cmp eax, 0
je _WinMain_failed
mov [LoadLibraryAddr], eax

; find GetProcAddress()
push GetProcAddressName
push dword [Kernel32Addr]
call LoadK32Function
cmp eax, 0
je _WinMain_failed
mov [GetProcAddressAddr], eax

; load user32.dll
push User32Name
call [LoadLibraryAddr]
cmp eax, 0
je _WinMain_failed
mov [User32Addr], eax

; find MessageBox()
push MessageBoxName
push dword [User32Addr]
call [GetProcAddressAddr]
cmp eax, 0
je _WinMain_failed
mov [MessageBoxAddr], eax

push 0
push WorkedMessage
push WorkedMessage
push 0
call [MessageBoxAddr]

; push 0
; push WorkedMessage
; push WorkedMessage
; push 0
; call _MessageBoxA@16
; jmp _WinMain_end
; push 0
; push FailedMessage
; push FailedMessage
; push 0
; call _MessageBoxA@16
ret 16

I could still improve a couple things. For one, it's probably a good idea to hash the api names and compare the hashes instead of using strcmp. Also, I know that strcmp is bloated (as is WinMain, but that's not really vital).

I might update this in the future with different methods of finding the base address of kernel32.dll, too. I know there are at least two other documented methods of finding it.

Anyways, tell me what you think, and constructive criticism is welcome as always :).
Why is Stefan standing on my shoulders...

[Reverse] IDA Plug-in Writing in C/C++ Tutorial

After spending a lot of time going through the header files in the IDA SDK as well as looking at the source to other people's plug-ins, I figured there should be an easier way to get started with writing IDA plug-ins. Although the header file commentary is amazingly thorough, I found it a little difficult navigating and finding things when I needed them without a lot of searching and trial-and-error. I thought that I'd write this tutorial to try and help those getting started as well as hopefully provide a quick reference point for people already proficient at developing plug-ins. I've also dedicated a section to setting up a development environment which should make the development process quicker to get into.

Get version 1.1 of the tutorial HERE (126 pages, 508KB PDF). This version is for IDA 5.4, though the SDK was mostly frozen since 4.9 so most things should still work.

Plug-in template:

Example plug-in source code:

Version 1.0 can still be obtained here and has also been published at CodeBreakers Journal.


[Virus] Self-modifying code-short overview for beginners


Today I would like to let us touch the area of self-modifying and obfuscated code. It’s not a secret that obfuscation is a basis “survival” technique for every modern malware. The business is simple: if your “kung-fu” is good enough – the probability that your malicious software would be able to survive (and successfully do its dirty job) is much higher. On the other side of the barricade there are countless AVs, IDSs, IPSs, firewalls, etc., which are claiming to be fully-automated intelligent malware detection tools. Both sides are motivated and very engaged in the battle so winners and losers are changing their places quite often. So today we would take a closer look to the "dark side".

The main reason for the article is my impression that so many people (surprisingly, the ones working in IT security and forensic) have really no idea how malware is working It is also is not clear how the tools for malware detection are dealing with it. And honestly, how you can fight with something if you don't know what it actually is? Know Your Enemy, dude! I want to demonstrate that self-modifying code is actually quite smart, but not necessarily too complicated mechanism. I also want us to become a malware investigators and for the very beginning try to hide the only one, single (and simple) function in our binary.

Oh yes, there are actually two articles. The first (this one) is a kind of introduction into code obfuscation. The second one will be an attempt to write fully working cryptor – the software which would allow us to execute malicious code and bypass antivirus protection! There is a small application prepared which illustrates everything below so you are welcomed to [download] it before the training. I will be intentionally omitting many technical details, just to give a broad view. Everything you need can be found later in thousand sources in the Internet.


  • Some knowledge of programming for Windows (examples will be in Delphi, but they are quite simple, so may be easily implemented in any other programming language). You definitely have to know what pointers are. It is also highly recommended to know what the Windows API is.
  • Basic knowledge of debugging binary applications for Windows would also be desired. We will be using famous and free OllyDBG.
  • Basic knowledge of assembler (I mean it: a very basic one. Don't run away now!). :-)

Ok, it's time to dance.

Part 1. Five Flavours of MessageBox


Self-modifying code is the kind of code that literally changes its own instructions while it is executing. Self-modification can be accomplished in a variety of ways depending upon the programming language and its support for pointers and/or access to dynamic compiler or interpreters. Here are some examples:

  1. Overlay of existing instructions (or parts of instructions such as opcode, register, flags or address).
  2. Direct creation of whole instructions or sequences of instructions in memory.
  3. Creating or modification of source code statements followed by a 'mini compile' or a dynamic interpretation (see eval statement).
  4. Creating an entire program dynamically and then executing it.

In our tutorial we will be playing with the code modification throughout execution ('on-the-fly') with emphasis on direct creation of instructions in memory.


Traditionally, we would start from something easy. And what can be more simple than showing a message box. :-)

procedure TForm1.Button1Click(Sender: TObject); begin   application.MessageBox('This is my first text', 'Info', mb_ok); //--- parameters: message, caption, style end;

Note: we provided three parameters to the Delphi function application.MessageBox. And the execution of this gives us the following (very predictable) result.

Nice. It would be interesting to see what the processor is doing when the binary is executed. Our good-old OllyDbg is coming with help. Ok, we are loading our .exe into the debugger and assuring the breakpoint on the API function MessageBoxA is set up.

Now run the binary and press the button nr 1 in our sweet application. Woop! Debugger stopped at the breakpoint and we may observe some interesting things.

Executed instructions (opcodes and disassembled code):

And the processor's stack:

What we may actually see is that the Delphi application.MessageBox function is nothing but a kind of a "wrap-up" for the Windows API function: MessageBoxA defined in the libraryuser32.dll. This function has not three but four parameters:

  • parent window's handle (address)
  • the text (address of the text in memory)
  • window caption (address of the caption in memory)
  • window style (buttons used, etc)

Last but not least: we also must have the address of the MessageBoxA function to be able to call it. Generally Windows API functions are used more-or-less the following way: their parameters are PUSHed in processor stack in reversed order (see the illustration above), then address of the function is copied to EAX and CALL is executed.

Once we know what is going on - we may try to call the same function (user32.MessageBoxA) directly in Assembler. Let's define some global variables first (I will tell you later why we use globals):

var   str1,   str2: pchar; //--- our strings   pAddr: integer; //--- address of the function

And now write the function itself:

procedure CallMessageBox(); asm   push dword ptr 0 //--- push style: 0   push dword ptr str1 //--- push DWORD parameter (caption)   push dword ptr str2 //--- push DWORD parameter (message)   push dword ptr 0 //--- push hOwner: 0   mov eax, pAddr   call eax //-- call address of the function, which is currently in EAX end;

This is the way we may call this function (when pressing button nr 2):

procedure TForm1.Button2Click(Sender: TObject); begin   str1 := 'Info';   str2 := 'This is my second text';   pAddr := dword(GetProcAddress(GetModuleHandle('User32.dll'), 'MessageBoxA'));    CallMessageBox; end;

The way we may get the address of the function exported by user32.dll is highlighted in red.Style = 0 (not defined) so the only "OK" button is shown. hOwner can also be 0 (new window's owner is a current application). Press the button nr 2 - everything works. Now let's check our executed code in the debugger:

...and the stack:

All is clear, right? Now maybe there should be a word said about why the "global variables" are used. This is because we want to have a "far" addresses: full DWORDs. If we would use a local variables - the code will be different because of optimization made by a compiler. And we need a simple and very clear picture now, isn't it?

Ok, everything up to this point was just a list of instructions, written in high-level programming language (Delphi) or low-level (Assembler), compiled and executed as a static binary code (a sequence of processor instructions).

Now let's think: we know how those processor instructions looks like. Why not to create exactly the same sequence of instructions but at runtime? So we can create kind of a "program A" which at runtime would write to the memory a sequence of some instructions (kind of "program B") and then execute them.

But before that let's check if we may access the opcodes of any existing function (read it from the memory). Because it would be much easier to copy the opcodes from existing functions not being using OllyDBG. (We are naturally lazy hackers, aren't we...) :)

This or that way, I prepared some simple function which can do that:

//---------------------------it allows to get opcodes from any existing function function copyOpcodesFromExistingFunction(sourceFunc: pointer; maxLength: integer): string; var i: integer;     p: pointer;     code: string; begin   result := '';   for i := 0 to maxLength do //--- now we can see the opcodes of this function   begin     p := ptr(dword(sourceFunc) + dword(i)); //--- craft pointer directly.     code := inttohex(byte(p^), 2);     result := result + code;     if code = 'C3' then break;   end; end;

Function copies everything from certain place in the memory (by given pointer to an analysed object/function) and reads the commands until it would meet C3 opcode, which is "return from the function" (or RET). Quck illustration what the pointer is here:

The similar approach is used for any other structures in memory (except maybe the fact that the data may not necessarily finish with a null byte). So let's check the opcodes of our functionCallMessageBox.

procedure TForm1.Button3Click(Sender: TObject); var   myAsm: string; begin   str1 := 'Info';   str2 := 'This is my third text';   pAddr := dword(GetProcAddress(GetModuleHandle('User32.dll'), 'MessageBoxA'));   caption := inttohex(pAddr, 8);    memo1.Text := copyOpcodesFromExistingFunction(@CallMessageBox, 40); //---take opcodes from existing function end;

This is what you would see when press the button nr 3:

Looks familiar, isn't it? :-) If we would add some line breaks - we would see the opcodes, previously shown by the debugger.

The technique described above, by the way, is the very nice way to review the opcodes for any function in Delphi. Kind of "self-debugger" or something... Great, now let's do the same, but the opposite way: now we would construct the same code at runtime. See this:

//---------------------------------construct our function manually (MessageBoxA) procedure TForm1.Button4Click(Sender: TObject); var   myAsm: string;   t: TByteArray;   oldProtect: DWORD;    dummyFunc: function: Integer; //--- dummy function begin   str1 := 'Info';   str2 := 'This is my fourth text';   pAddr := dword(GetProcAddress(GetModuleHandle('User32.dll'), 'MessageBoxA'));    myAsm := ' 6800000000' + //--- push style: 0            ' FF35' + inttohex(swapEndian(dword(@str1)), 8) +  //--- push dword: caption address            ' FF35'  + inttohex(swapEndian(dword(@str2)), 8) + //--- push dword: message address            ' 6800000000' + //--- push hOwner: 0            ' B8' + inttohex(swapEndian(pAddr), 8) + //--- mov EAX, dword: API function address            ' FFD0' + //--- call EAX            ' C3'; //--- RET (return from function)    t := StringToArrayOfByte(myAsm);    @dummyFunc := @t; //--- point the inline function to our byte array   VirtualProtectEx(0, @dummyFunc, SizeOf(dummyFunc), PAGE_EXECUTE_READWRITE, @oldProtect);  //--- allow the page where the code resides - treated as executable    dummyFunc; //--- run our hand-crafted function end;

This is what's happening when you press the button nr 4.

  1. We assign values to our string variables ("info", "fourth text").
  2. We are retrieving the address of the function we will be calling (MessageBoxA).
  3. We create the string (myAsm) which is ASCII-hex-encoded list of our instructions to be executed.
  4. Our instructions list (myAsm) is written as bytes into memory TByteArray.
  5. We assign the pointer of the dummy function to the TByteArray.
  6. We mark the memory page where our TByteArray (actually - our new function) resides as code (PAGE_EXECUTE_READWRITE), so our innocent bytes (data) becomes a code and can be executed.
  7. The function (our brand new code: dummyFunc) is successfully executed by user.

The result:

Hurray, it works! Here some important things:

  • Keep attention to this definition: TByteArray = array[1..200] of byte (Important!)
  • We must keep in mind the reversed sequence of parameters.
  • We must swap endians for all addresses (A1B1C1D1 becomes D1C1B1A1). Don't ask me why - processor just works this way.

Important remark: we know perfectly that all strings explicitly defined in source code will be clearly visible in our binary. All instructions after compilation are also visible in our binary. You will find them in a one second, being armed with a hex editor. And this is also exactly what all antiviruses are doing: checking for certain combinations of bytes in binaries(on hard drive) and/or in memory, before execution of the program. See our code inside of the binary:

Of course AV's don't care about our innocent MessageBoxA, but for sure may keep much more attention e.g. to the following functions: VirtualProtect, SetThreadContext,GetThreadContext, WriteProcessMemory, ReadProcessMemory, CreateProcess, etc.

So what we can do to make it more difficult to detect what our program will be doing?

  • We may encrypt all strings (all our data, our code which will be executed and all keywords like "User32.dll" or "MessageBoxA".
  • We may use undocumented API functions.

Whaaat? How you can use something which is not documented? And what the hell it is? In short: it's kind of a "box inside the box". :-) Something like this:

So we already know that the Delphi's Application.MessageBox is actually calling MessageBoxA. But there is more: the MessageBoxA is internally calling another function: MessageBoxExA. This inner function may have different (or additional) parameters. We can easily proof it with our debugger by setting up the break on MessageBoxExA:

The result (clearly MessageBoxA is calling MessageBoxExA):

Parameters on stack:

We clearly see one more additional parameter appeared: languageID. Btw, it's a nice and simple example of API's reverse engineering, isn't it. We may confirm our findings in MSDN(assuming the function is documented) or google for it. Ok, so what we can do now, we may construct our opcodes for the MessageBoxExA instead of MessageBoxA. This is it:

procedure TForm1.Button5Click(Sender: TObject); var   myAsm: string;   t: TByteArray;   oldProtect: DWORD;    dummyFunc: function: Integer; //--- dummy function begin   str1 := pchar(simpleDecryption('B6919990')); //--- encrypted text: "Info"   str2 := pchar(simpleDecryption('AB97968CDF968CDF9286DF9996998B97DF8B9A878B')); //--- encrypted text: "This is my fifth text"   pAddr := dword(GetProcAddress(GetModuleHandle(pchar(simpleDecryption('AA8C9A8DCCCDD19B9393'))), //--- encrypted text: "User32.dll"                                 pchar(simpleDecryption('B29A8C8C9E989ABD9087BA87BE')))); //--- encrypted text: "MessageBoxExA"    myAsm := ' 6800000000' + //--- push languageId: 0            ' 6800000000' + //--- push style: 0            ' FF35' + inttohex(swapEndian(dword(@str1)), 8) +  //--- push dword: caption address            ' FF35'  + inttohex(swapEndian(dword(@str2)), 8) + //--- push dword: message address            ' 6800000000' + //--- push hOwner: 0            ' B8' + inttohex(swapEndian(pAddr), 8) + //--- mov EAX, dword: API function address            ' FFD0' + //--- call EAX            ' C3'; //--- RET (return from function)    memo1.Text := myAsm;   t := StringToArrayOfByte(myAsm);    @dummyFunc := @t; //--- point the inline function to our byte array   VirtualProtectEx(0, @dummyFunc, SizeOf(dummyFunc), PAGE_EXECUTE_READWRITE, @oldProtect);  //--- allow the page where the code resides - treated as executable    dummyFunc; //--- run our hand-crafted function end;

Note that strings are also encrypted now. The myAsm variable may also be initially encrypted (I left it as it is - to make everything a little bit more clear). There are some primitive encryption functions used:


function simpleEncryption(dataIn: string): string; var i: integer; begin   for i := 1 to length(dataIn) do result := result + inttohex(255 - ord(dataIn[i]), 2); end;


function simpleDecryption(dataIn: string): string; var i: integer; begin   for i := 1 to length(dataIn) div 2 do result := result + chr(255 - strToInt('$' + copy(dataIn, i * 2 - 1, 2))); end;

When you press the button nr 5 - result is exactly as expected: Message box is popping-up.

Even if our suspicious antivirus for some reason is sensitive to the opcodes of MessgeBoxA (assuming this function may be used for something bad) - it may not necessarily be so sensitive to MessageBoxExA. And this is exactly what we want to achieve!


The simple self-modifying and obfuscating mechanism described above may be surprisingly good to omit antivirus protections. Now, being knowing all this, we may try to do something more serious: write our own cryptor, which should allow us to "smuggle" a 3rd party malicious code to any target system. Stay tuned and w8 for the 2nd part of the tutorial.

I would like to encourage you for feedback, which would be very useful. This would help us to adjust the texts and illustrations, avoid possible uncertainties and make everything even more easy to read and understand. :)