Most Popular Blogs

  1. The Point-R technique


    While trying to track down a really difficult problem in the production version of our software that only manifested itself in certain configurations on SunW,
    i thought to myself... There Must Be A Better Way!

    So here, i present you the Point-R technique.
    It is very similar to the hmemcpy technique which we all miss so much, in that it will give you a jump start with any debugging problem.

    Just load the problematic file, be it a program of yours or something you need to crack, into ida and run point-r.upb.idc.

    Set a breakpoint on Point-R, let it run until the breakpoint breaks and you will be at the core of the problem at hand.

    The script will find Point-R by utilizing a series of successive complex approximations, much in the same way you would find a square root with some fixed precision.

    Enjoy and comment/enhance it!
    (and do not hesitate to correct my spelling/style errors [LLXX])

    Updated October 25th, 2007 at 21:01 by upb

    Attached Thumbnails Attached Files
  2. Beware of int 2c instruction

    In the last days I played a little with Win32.Virtob virus, thanks to Kayaker for passing it out to me. It’s a nice virus with some interesting tricks. You can read a detailed analysis made by Kayaker from his recent blog entries.
    In this post I’m not going to talk about the malware itself, I simply focus my attention on an single instruction: int 2c. The instruction is located in the beginning of the virus and I spent some time on it trying to answer Kayaker’s question: is “int 2c” used as an antidebug trick? I don’t have an answer for the question, but after some tries I came up with something that can be interesting.

    execution changes the content of some registers, but one of them (in particular edx) is always changed in the same way. edx contains the address of the instruction that follows the int 2c instruction.
    100: mov edx, 80   <– edx = 0×80
    105: int 2c   <– it changes edx value
    107: xor eax, eax   <– here: edx = 0×107
    Pretty weird. To know why you have to look at ntoskrnl code (starting from KiSetLowWaitHighThread), it’s pretty easy to find out why. Here’s the last part of the int2c code:
    804d4f95 pop     edx   <-- edx is changed here
    804d4f96 add     esp,8
    804d4f99 pop     ecx
    804d4f9a sti
    804d4f9b sysexit
    Sysexit is the key of this snippet. The function is used when there’s a transition from ring0 to ring3 code. ring3.eip is updated with ring0.edx value. That’s why edx contains the magic value, if you want to go back into ring3 world you have to put the return address into edx.
    Is this fact important? Not really, per se. There’s a interesting use of this behaviour btw, infact it could be used inside an obfuscation engine or as an anti Ollydbg trick.

    Look at this simple and stupid sample I wrote (attached at the end of the post):
    00401000 LEA EDX,DWORD PTR DS:[403000]      ; 403000 -> "easy sample"
    00401006 PUSH EDX
    00401007 INT 2C
    00401009 PUSH 0                             ; Style = MB_OK|MB_APPLMODAL
    0040100B INT 2C
    0040100D SUB BYTE PTR DS:[EDX+6],9          ; 403006 = ‘X’
    00401011 LEA EAX,DWORD PTR DS:[403015]      ; 403015 -> “I’m the caption”
    00401017 PUSH EAX                           ; Title_1: “I’m the caption”
    00401018 INT 2C
    0040101A XOR BYTE PTR DS:[EDX+6],1D         ; 403006 = ‘E’
    0040101E LEA EAX,DWORD PTR DS:[403038]      ; 403038 -> “I’m the text”
    00401024 PUSH EAX                           ; Text_1: “I’m the text”
    00401025 INT 2C
    00401027 PUSH 0                             ; hOwner = NULL
    00401029 INT 2C
    0040102B CALL <JMP.&user32.MessageBoxA>     ; MessageBoxA, display the 1° message box
    00401030 POP EDX                            ; edx -> “easy sEmple”
    00401031 PUSH 0                             ; Style = MB_OK|MB_APPLMODAL
    00401033 PUSH msgbox.0040300C               ; Title_2: “Int2c…”
    00401038 PUSH EDX                           ; Text_2: “easy sEmple” (”sEmple” and not “sample”)
    00401039 PUSH 0                             ; hOwner = NULL
    0040103B CALL <JMP.&user32.MessageBoxA>     ; MessageBoxA, display the 2° message box
    00401040 PUSH 0                             ; ExitCode = 0
    00401042 CALL <JMP.&kernel32.ExitProcess>   ; ExitProcess
    This is the static analysis of the snippet above, it’s not right! Try running the attached exe (I can assure you it’s not dangerous) and you’ll see the real behaviour of this piece of code. It displays two message boxes with the real messages, the first one with:
    caption: “Int2c…”
    text: “Obfusction sample”
    and the second with:
    caption: “Int 2c…”
    text: “easy sample” (it’s not “sEmple”)

    Why? Well, it’s pretty simple:
    0040100B  CD 2C          INT 2C                          ; int2c changes edx value
    0040100D  806A 06 09     SUB BYTE PTR DS:[EDX+6],9       ; edx = 40100D, it changes 403015 into 40300C
    00401011  8D05 15304000  LEA EAX,DWORD PTR DS:[403015]   ; eax = 40300C, 40300C -> “Int2c…”
    Execution of int 2c changes edx value, and if you don’t know anything about it you’ll have a wrong static analysis. It’s a simple code obfuscation, but you have to take care of it for sure.

    Now, try loading the attached exe file into Ollydbg. These are the results I got from my tests based on an XP sp1 and sp2 machines.

    Ollydbg and XP sp1
    The file runs fine when you launch it with F9 key, it shows the real messages.
    The problems arise when you step through the code with “step into”(F7) or “step over”(F8) modes. No matter if you are stepping with F7 or F8, executing an int 2c instruction the debugger won’t break unless you have inserted a bpx onto one of the next instructions. A perfect trick for those who don’t know how to deal with it, you step the instruction and the malware performs all his nasty operations…

    Ollydbg and XP sp2
    The file runs fine when you launch it with F9 key, it shows the real messages.
    F7 and F8 modes have the same behaviour, Ollydbg stops at the second instruction after “int 2c“; the problem is that edx value is not updated with the correct address value. Here’s what happen:
    00401006 PUSH EDX                    ; edx = 403000
    00401007 INT 2C                      ; F7 or F8 here and Ollydbg
    00401009 PUSH 0                      ; will break at 40100B
    0040100B INT 2C                      ; F7 or F8 here and Ollydbg will
    0040100D SUB BYTE PTR DS:[EDX+6],9   ; break here due to the exception:
    ; “Access violation when writing to [00000005]”

    The exception occours because (at 40100D) edx value is 0xFFFFFFFF. edx value was changed by “int 2c” at 40100B.
    The only way to obtain a correct edx value is to use F9 setting a bpx at 40100D.

    I tried the same exe with Ida debugger on a XP sp2 machine. You can step using F8 without problem, but not with F7 because you’ll get the same access violation.

    I think it’s definitely something to take care of, what do you think?

    (File available here:
  3. MmGetSystemRoutineAddress : forwards on vista

    Very frustrating when you figure that this export can't resolve forwarded APIs. Here is one example from Vista:

    .edata:8002F485 ; Exported entry   1. ExAcquireFastMutex
    .edata:8002F485                 public ExAcquireFastMutex
    .edata:8002F485 ExAcquireFastMutex db 'ntoskrnl.ExiAcquireFastMutex',0
    .edata:8002F4A2 aExreleasefastm db 'ExReleaseFastMutex',0
    .edata:8002F4B5 ; Exported entry   2. ExReleaseFastMutex
    .edata:8002F4B5                 public ExReleaseFastMutex
    .edata:8002F4B5 ExReleaseFastMutex db 'ntoskrnl.ExiReleaseFastMutex',0
    .edata:8002F4D2 aExtrytoacquire db 'ExTryToAcquireFastMutex',0
    .edata:8002F4EA ; Exported entry   3. ExTryToAcquireFastMutex
    .edata:8002F4EA                 public ExTryToAcquireFastMutex
    .edata:8002F4EA ExTryToAcquireFastMutex db 'ntoskrnl.ExiTryToAcquireFastMutex',0
    When you use MmGetSystemRoutineAddress it will return to you address of string. It won't resolve forwarded API properly.

    The best way is to use own MmGetSystemRoutineAddress instead of the one provided by windows kernel...
  4. SoftICE Installation.

    Recently ive spent a lot of time installing SoftICE on various machines and i want to post
    all the various problems i came accross and ones i have solved.

    DriverSuite v3.2


    first of all before installing softice you should install the default driver version
    of your graphic card, this means the original driver that came with the machine or
    the earliest version you can find, both ATI and NVIDIA offer a back catalogue of their
    previous driver versions.

    Keep the INIT string to a basic x; before you have softice working
    Disable mouse support, no real reverser needs a mouse in softice ;-)
    Make sure you install DirectX
    Use the Detect and Test buttons in the video section of setup.


    1) ".. A device attached to the system is not functioning .. "

    I have solved this problem many times by ..

    1.) Installing a different graphic driver.
    2.) Disabling SPTD.SYS from the registry
    HKEY_LOC_MACHINE/system/services/currentcontrolset/SPTD/Start change to 4

    2) Upon starting softice the window flashes by then a system freeze occurs.

    I have solved this problem only a "few" times by ..

    1.) In winice.dat place the string NTSYMBOLS=ON, use the symbol loader to grab symbols for
    kernel32.dll user32.dll ntoskrnl.exe hal.dll gdi.ll convert and load these.

    If this doesnt work then

    2.) replace the osinfo.dat and osinfob.dat in system32\drivers with new ones from the
    compuware ftp, you can google for links.

    If this doesnt work, try undo option 1

    The above works for me frequently, however on non freshly installed systems conflicts can
    occur with other software. If you really want softice to work then you are going to have
    to spend time disabling software, AntiVirus/Spyware is a good start, and not just disabling
    them but uninstalling any software which may install a kernel mode driver with system hooks
    to identify the problem, However i recommend a freshly installed machine dedicated for
    kernel mode debugging.

    Once up and running you can use my pretty INIT line

    INIT="lines 60;ws 5;wc 25;wd 6;set font 2;color 03 4e 4e 1b 1b;x;"


    after installing XPSP2 you must install vmware tools, then save and shutdown the machine,
    next you must edit the .vmx file and place in the following lines

    vmmouse.present = FALSE
    svga.forceTraces = "TRUE"

    I invite people to add comments to help build an informative thread on softice problems,
    please try and structure your reply in a clear way, such as,
    Problem: x Solution: x

  5. Reverse Engineering the flash virtual machine


    i recently started a small project where i try to obfuscate a small flash sample. i'm especially interested in the virtual machine and the interpreted bytecode. after some googling i found two interesting papers from adobe itself. i was pretty suprised to see that adobe provides such a good documentation about the virtual machine and its bytecode.

    you can take a look at the pdfs here:


    SWF and FLV File Format Specification -

    For the last document you will need to step through the license process of adobe. but dont be shy they offer a free license for a year, then you must refresh your license to use the pdf.

    probably this information is wide spread but i think it will be interesting for a few people.

    most of the obfuscator out there i saw for flash are rather crapy, i think there should be better ways to protect a swf application.



    Updated February 25th, 2008 at 09:07 by OHPen

    The incredible world of virtual machines and byte code
  6. Process Memory Dumper for Credentials Disclosure Vulns


    This last period was full of intersting findings, I've published two advisoryes on Bugtraq:


    So I also coded a Process Memory Dumper, useful to improve these vulns.
    It can be downloaded here:


    See you to the next post..
  7. Trojan-PSW.Win32.OnLineGames.eos Reversing

    Win32.OnLineGames is a PSW Trojan, which works as a Password Stealer, specifically written to steal online gaming passwords.

    00401314 add eax, esi
    00401316 lea eax, ds:401442h
    0040131C jmp eax ;00401442

    At the entry point, code flow jumps to 00401442

    00401442 push ebp
    00401443 mov ebp, esp
    00401445 sub esp, 52Ch
    0040144B call ds:GetCurrentThreadId
    00401451 push eax
    00401452 call ds:GetThreadDesktop
    00401458 test eax, eax
    0040145A jnz short loc_40145D
    0040145C int 3 ; Trap to Debugger
    0040145D push ebx
    0040145E push esi
    0040145F push edi
    00401460 mov edi, offset aCzxsderdaksiic ; "CZXSDERDAKSIICS_MX"
    00401465 xor esi, esi
    00401467 push edi ; String
    00401468 push esi ; NULL
    00401469 push EVENT_ALL_ACCESS
    0040146E call ds:OpenEventA

    Obtains the handle to the desktop associated to the executable itself and opens the handle of an existing event called CZXSDERDAKSIICS_MX, if event exists its own handle is closed, else a new event (called CZXSDERDAKSIICS_MX9 is created with standard SecurityAttributes.

    00401486 mov [ebp-10h], eax
    00401489 mov edi, offset off_401154 ;Edi points to an array of strings, that are a list of executables
    0040148E mov ecx, [edi]
    00401490 call sub_401798 ;Check if the searched process is running
    00401495 cmp eax, esi
    00401497 jz short loc_4014B2 ; If no, go to the next process
    00401499 push eax
    0040149A push esi
    0040149B push 1F0FFFh
    004014A0 call ds:OpenProcess
    004014A6 cmp eax, esi
    004014A8 jz short loc_4014B2
    004014AA push esi
    004014AB push eax
    004014AC call ds:TerminateProcess
    004014B2 add edi, 4
    004014B5 cmp edi, offset dword_40115C ;Next process to search
    004014BB jl short loc_40148E
    004014BD call sub_40131E ;AdjustTokenPrivilege

    The searched executables: Twister.exe, FilMsg.exe

    0040151B call ds:GetSystemDirectoryA
    00401521 mov edx, offset asc_401204 ; "\\"
    00401526 lea ecx, [ebp-11Ch] ;points to the System Directory
    0040152C call sub_40174A
    00401543 call ds:GetModuleHandleA
    00401549 push offset aMndll ; "MNDLL"
    0040154E push 65h
    00401550 push eax
    00401551 mov [ebp+8], eax
    00401554 call ds:FindResourceA
    0040155A push eax ;00402048
    0040155B mov [ebp-4], eax
    0040155E push dword ptr [ebp+8]
    00401561 call ds:SizeofResource
    00401567 push dword ptr [ebp-4]
    0040156A mov [ebp-18h], eax
    0040156D push dword ptr [ebp+8]
    00401570 call ds:LoadResource
    00401576 push eax ;00402070
    00401577 call ds:LockResource
    0040157D cmp eax, esi
    0040157F mov [ebp-4], eax
    00401582 jnz short loc_40158E
    00401584 push dword ptr [ebp-10h]
    00401587 call edi ; CloseHandle
    00401589 jmp loc_4016C6

    The code here is clear, after enstablishing the System Directory, searches for a Resource type "MNDLL" and next loads it, the LoadResource give us an intersing location 00402070, that's an executable image, exploring this executable we can see some intersing strings ConfigAreaName game.ini

    004015A6 add esp, 0Ch
    004015A9 lea edx, [ebp-428h]
    004015AF lea ecx, [ebp-11Ch]
    004015B5 call ScansFor ;call sub_40176F (searches for csavpw0.dll)
    004015BA lea edx, [ebp-324h] ; SystemDirectory
    004015C0 lea ecx, [ebp-11Ch] ; csavpw0.dll
    004015C6 call sub_40174A
    004015CB lea eax, [ebp-11Ch]
    004015D1 push eax
    004015D2 call dseleteFileA
    004015D8 push esi
    004015D9 push 80h
    004015DE push 2
    004015E0 push esi
    004015E1 push esi
    004015E2 lea eax, [ebp-11Ch]
    004015E8 push 40000000h
    004015ED push eax
    004015EE call ds:CreateFileA
    004015F4 cmp eax, 0FFFFFFFFh
    004015F7 mov [ebp-14h], eax
    004015FA jnz short loc_401605
    004015FC inc dword ptr [ebp+8]
    004015FF cmp dword ptr [ebp+8], 0Ah
    00401603 jb short loc_401591 ;Go to the next cycle

    If there is another csavpw0.dll, is firstly deleted and next recreated, if creation fails is performed the same routine for csavpw1.dll, csavpw2.dll.

    In my case csavpw2.dll is founded

    00401608 push esi
    00401609 push ecx
    0040160A push dword ptr [ebp-18h] ; Size: 4C00
    0040160D push dword ptr [ebp-4] ; Buffer: 00402070
    00401610 push eax
    00401611 call ds:WriteFile
    0040161A call CloseHandle
    0040161C push ebx
    0040161D call ds:Sleep
    00401623 lea ecx, [ebp-11Ch] ;C:\WINDOWS\system32\csavpw2.dll

    csavpw2.dll is filled up with the discovered Resource.

    00401630 push ebx
    00401631 lea eax, [ebp-220h]
    00401637 push offset aCzxsderdaksi_0 ; "CZXSDERDAKSIICS_%d"
    0040163C push eax
    0040163D call ds:wsprintfA
    00401643 add esp, 0Ch
    00401646 lea eax, [ebp-220h]
    0040164C push eax ;CZXSDERDAKSIICS_0
    0040164D push esi
    0040164E push 1F0003h
    00401653 call ds:OpenEventA
    00401659 cmp eax, esi
    0040165B jz short loc_401666
    0040165D push eax
    0040165E call CloseHandle
    00401660 inc ebx
    00401661 cmp ebx, 0Ah
    00401664 jb short loc_401630

    As usual it searches for CZXSDERDAKSIICS_0, CZXSDERDAKSIICS_1, CZXSDERDAKSIICS_2 when the OpenEvent FAILS we have this:

    0040166C push 104h
    00401671 push eax
    00401672 push esi
    00401673 call ds:GetModuleFileNameA
    00401679 lea eax, [ebp-220h] ;CZXSDERDAKSIICS_2
    0040167F lea edx, [ebp-52Ch] ;Path of our virus executable
    00401685 push eax ;CZXSDERDAKSIICS_2
    00401686 lea eax, [ebp-11Ch]
    0040168C push eax ;C:\WINDOWS\system32\csavpw2.dll
    0040168D mov ecx, offset a8dfa290443ae89 ; "{8DFA2904-43AE-8929-9664-4347554D24B6}"
    00401692 call sub_40124E

    -> call sub_40124E Creates a RegKey in HKEY_CLASSES_ROOT with CLSID\{8DFA2904-97C43AE-8929-9664-4347554D24B6} and setted some values as ExeModuleName, DllModuleName, SobjEventName

    004016B5 push eax ; csavpw2.dll
    004016B6 call edi ; LoadLibraryA
    004016B8 push esi
    004016B9 call ds:ExitProcess
    004016BF push eax
    004016C0 call ds:CloseHandle

    Trojan Removal

    1) Delete the Trojan file: csavpw0/1/2/etc.dll

    2) Delete the following CLSID CLSID\{8DFA2904-97C43AE-8929-9664-4347554D24B6}

    See you to the next post..
    Reverse Engineering
  8. Rebel.NET

    As promised, I'm hereby releasing the Rebe.NET software.

    Rebel.NET is a rebuilding tool for .NET assemblies which is capable of adding and replacing methods and streams. It's possible to replace only a limited number of methods or every method contained in a .NET assembly. The simplicity of Rebel.NET consists in the replacing process: one can choose what to replace. Rebel.NET is, mainly, a very solid base to overcome every .NET protection and to re-create a fully decompilable .NET assembly. As such, Rebel.NET has to be considered a research project, not an encouragement to violate licensing terms.

    As I have written the software and the article in this week when during my sickness (fever), I'm expecting bugs and typos. Please report them.

    Of course, I've tested the Rebel.NET with more advanced .NET assemblies than those presented in the guide.

    Updated April 25th, 2008 at 14:59 by Daniel Pistelli

  9. Intel VT and cpuid break

    Do you want to use cpuid as int 3 or any other event? Well Intel VT allows us that, as cpuid always generates VM-Exit. In this case what we do is:

    1. Read Guest Cr3 to check correct process
    2. inject int 3 event into Guest
    3. SoftICE will popup if i3here on is set
    4. Enjoy

    bin/src ->
  10. .NET Internals and Native Compiling

    Strictly speaking it means converting the MSIL code of a .NET assembly to native machine code and then removing the MSIL code from that assembly, making it impossible to decompile it in a straightforward way. The only existing tool to native compile .NET assemblies is the Salamander.NET linker which relies on native images to do its job. The "native images" (which in this article I called "Native Framework Deployment") technique is quite distant from .NET internals: one doesn't need a good knowledge of .NET internals to implement it. But, as the topic is, I might say, quite popular, I'm going to show to the reader how to write his Native Framework Deployment tool if he wishes to. However, the article will go further than that by introducing Native Injection, which means nothing else than taking the JIT's place. Even though this is not useful for commercial protections (or whatever), it's a good way to play with JIT internals. I'm also going to introduce Native Decompiling, which is the result of an understanding of .NET internals. I'm also trying to address another topic: .NET Virtual Machine Protections.

    I hope you'll enjoy this.

    P.S. As always, if you notice typos, please report them.

    Updated May 25th, 2008 at 10:53 by Daniel Pistelli

  11. Control Flow Deobfuscation Part 3

    Now we have:

    So to deobfuscate we only need one more thing:
    • A way to order the vertices

    Interestingly, we could also make a obfuscator in this way. All we have to do is put the vertices in a random order.

    So to deobfuscate we can't just use any ordering. We have to use one that is 'intuitive' and 'natural'. Unfortunately these words mean nothing to a computer; we'll have to specify them more carefully.

    Let's start simple. In which order would you place these vertices if you wanted to deobfuscate?

    I think we can agree that 1-2-3 is he right order.
    3-1-2 is bad because we have to start with 1: this tells everyone that the function starts there.
    1-3-2 is bad too, but why? For one it creates more branches than necessary, but I think this is not the reason it is hard to read. I think the reason is that we go backwards from 2 to 3. Most of us like to read in one direction: from top to bottom or from left to right.

    Another one:

    The right order here is 1-2-4-3 or 1-4-2-3.
    1-2-3-4 is wrong because 4 then goes backwards to 3.

    We can say: the order is right iff for all edges, the start of the edge comes before the end of the edge. This ordering is known as a topological ordering. There are various ways to compute it; it is important to remember that one is the reverse postorder of a depth-first traversal.

    This might all sound like gibberish to you, so feel free to take a pause and look up some of the underlined words. Here's a little pseudocode example for the reverse postorder:
        order = []
        for each child in vertex.edges
            order = reverse_postorder(child) + order
        order = vertex + order
        return order

    Well, so far so good. But what to think of this one:

    I'd say that the best ordering is 1-2-3-5-4. Some compilers order this as 1-5-2-3-4. Even 1-3-5-2-4 isn't unreasonable. But according to our ordering rules, they are all wrong.

    If your graph has a cycle, it isn't possible to get a perfect ordering. We can't have 2 before 3, 3 before 5 and 5 before 2 at the same time, so we'll have to go backwards at least one time.

    Something like 1-4-2-3-5 is even more wrong though. Now we have two backward edges, 3 to 4 and 5 to 2.

    One way to solve the problem is like this:

    We contract the vertices of the strongly connected component (a generalization of cycles) into one "supervertex". Now we order that and get 1-I-4. Then we order I: first we pick one vertex to start, I like to get the one that has most edges to it from outside I, but it doesn't matter much. In this example we pick 2. Then we order the rest (and if we find sub-SCC's in I we recurse). So here we get 3-5. Then the final order is 1-2-3-5-4.

    Now thinking that out is one thing, implementing it is another. The most obvious problem is how to find the SCC's. Luckily some very smart people already figured it out for us. We'll use Tarjan's strongly connected components algorithm. It is a bit hard to understand, but explains it very clearly.

    So, are we done now? Is the following algorithm enough:
    1. Find all SCC's
    2. Collapse them into supervertices
    3. Order the resulting graph
    4. Apply this algorithm to all supervertices in the result

    Yes, in a certain sense. It works fine, but it's quite a lot to code (especially in C) and it's pretty inefficient.

    / this is the clever part
    Now both Tarjan's algorithm and the reverse postorder are based on depth first search. So maybe it's possible to combine them? It turns out we can indeed do this and save ourself a lot of work. The only modification we need to do is:
    • Whenever we find an SCC, we check if it is trivial (one vertex). If so, we add it to the order. Else we order the SCC and put the result in the order.

    So the final algorithm is:
    get_order(first_vertex, vertices_to_consider):
        /* Define some variables */
        order = []
        stack = empty_stack
        cur_dfsnum = 0
        index = []
        low = []
        /* Nested function, has access to above variables (closure) */
            index[cur_vertex] = cur_dfsnum
            low[cur_vertex] = cur_dfsnum
            push cur_vertex on stack
            for each child in cur_vertex.edges where child in vertices_to_consider
                if index[child] == "To be done"
                    low[cur_vertex] = min(low[cur_vertex], low[child])
                else if index[child] == "Done"
                    /* Do nothing */
                    low[cur_vertex] = min(low[cur_vertex], index[child])
            if low[cur_vertex] == index[cur_vertex]
                /* we found an SCC */
                scc = []
                    popped = pop from stack
                    scc += popped
                    index[popped] = "Done"
                until popped == current_vertex
                if scc.length == 1
                    order = cur_vertex + order
                    order = get_order(choose_first(scc), scc) + order
        /* visit() ends */
        for vertex in vertices_to_consider:
            index[vertex] = "To be done"
        /* Special-case the start vertex to prevent infinite recursion */
        index[first_vertex] = "Done"
        for each child in first_vertex.edges where child in vertices_to_consider
            if index[child] == "To be done"
        order = first_vertex + order
        return order
    I omitted the choose_first function because it isn't important.

    Now we have every part, putting it together is simple:
        already_done_vertices = empty
        cfg = makecfg(bytecode)
        order = get_order(cfg, already_done_vertices)
        return rebuild_from_order(cfg, order)

    Well that's it mostly. I wanted to show how to do this so maybe someone doesn't have to spend weeks figuring this stuff out and because I think
    reverse postorder + Tarjan's strongly connected components algorithm = approximate topological ordering
    is a very nice insight.

    P.S. Sorry, my tool to do this for .NET is currently private because I'm not interested in an arms race. The ideas behind it are more important anyway
  12. nonintrusive tracer on x64

    Well time has come to dig a little bit into x64 systems, and to move our lovely tools and ideas to that system.

    Lets have a look at KiUserExceptionDispatcher from ntdll.dll:

    .text:0000000077EF31B0                 public KiUserExceptionDispatcher
    .text:0000000077EF31B0 KiUserExceptionDispatcher:              
    .text:0000000077EF31B0                 mov     rax, cs:Wow64PrepareForException
    .text:0000000077EF31B7                 test    rax, rax
    .text:0000000077EF31BA                 jz      short loc_77EF31CB
    .text:0000000077EF31BC                 mov     rcx, rsp
    .text:0000000077EF31BF                 add     rcx, 4D0h
    .text:0000000077EF31C6                 mov     rdx, rsp
    .text:0000000077EF31C9                 call    rax ; Wow64PrepareForException
    .text:0000000077EF31CB loc_77EF31CB:                         
    .text:0000000077EF31CB                 mov     rcx, rsp
    .text:0000000077EF31CE                 add     rcx, 4D0h
    .text:0000000077EF31D5                 mov     rdx, rsp
    .text:0000000077EF31D8                 call    RtlDispatchException
    .text:0000000077EF31DD                 test    al, al
    .text:0000000077EF31DF                 jz      short loc_77EF31ED
    .text:0000000077EF31E1                 mov     rcx, rsp
    .text:0000000077EF31E4                 xor     edx, edx
    .text:0000000077EF31E6                 call    RtlRestoreContext

    Wow64PrepareForException is used only when loading wow64 process, so in "native x64" environment this variable is set to 0, and we can use that variable to write our own SEH handler in asm or nonintrusive tracer. Well let's cut to the point and see some real code:

                            mov     rax, KiUserExceptionDispatcher
                            xor     rbx, rbx
                            mov     ebx, dword ptr[rax+3]
                            add     rbx, rax
                            add     rbx, 7
                            mov     rax, offset __mykiuser
                            mov     [rbx], rax
                            xor     rax, rax
                            mov     [rax], rax
                            xor     r9, r9
                            mov     r8, offset szntdll
                            mov     rdx, offset szkiuser
                            mov     rcx, 0
                            callW   MessageBoxA
                            xor     rcx, rcx
                            callW   ExitProcess
    __mykiuser:             add     qword ptr[rdx+0F8h], 3
                            mov     rcx, rdx
                            xor     rdx, rdx
                            callW   RtlRestoreContext
    If everything worked as planned, MessageBoxA will be shown... simple isn't it
  13. SymbolFinder

    Dunno if this is just me or this is for real, but if someone tries to google for some kind of example of symbol lister it will endup in dead-end (maybe I should work on my google skils ), anyway, I spent last 2 days playing and figuring these symbols (great MS simply points in MSDN to PDB documentation... where is that thing!??!!?), to write this enum, struct, symbol lister and decided to share my source so there can be at least one refference on how to list and parse symbols...

    Hope someone will find it usefull
  14. custom gpa spy

    read above topic to know how this idea was born well actually this idea was in my mind for almost a two years, but never found it useful to fully develop working code, but after reading this topic, and comments at posted link, I've decided to give it a go status.

    In short : at above link, you will find link to the other site which has statistic of used functions in common files. On other hand, many are missed due to GetProcAddress, and not to mention many being missed due to custom GetProcAddress. So how to spy custom GetProcAddress!?!? well read the code and you will see.

    This could be useful for protection profiling, and there are some other ways which I would use to deal with this, but for now, it seems ok, just so you get the basic idea. code is really messy, as I hate writing ring3 debuggers...

    full code and sample binary:
  15. Netsons killed my Website

    Netsons without any advice, suspended my account, now I don't have a web-space, if possible I'll try to find some Webspace.

    Giuseppe 'Evilcry' Bonfa'
Page 4 of 5 FirstFirst 12345 LastLast