In this blog post we will implement a custom encoding scheme and implement a custom decoder for it.
The implementation of the encoder
For example if my shellcode looks like "\xa1\xb2\c3\d4' the encoder will generate "\xa0\xa0\xb3\xb3\x5d\x5d\x62\x62\x32\x32\x5d\x5d\x65\x65\x35\x35"
The implementation of the decoder
The implementation of the encoder
- Copy some existing shellcode
- For each shellcode value xor with 0x1
- Append twice the same value.
- Print the final shellcode
- We need to remember the actual size of the shellcode without encoding
For example if my shellcode looks like "\xa1\xb2\c3\d4' the encoder will generate "\xa0\xa0\xb3\xb3\x5d\x5d\x62\x62\x32\x32\x5d\x5d\x65\x65\x35\x35"
The implementation of the decoder
- Take the encoded shellcode
- As .text section locations are not writable, we will create some reserved space in .bss segment
- Read pointer ESI to read from the encoded shellcode location and a write pointer EDI to write the decoded shellcode.
- Read each alternative positions of encoded shellcode because each value is repeated.
- For each byte we read , we will xor with 0x1 and then store at the location pointed by EDI
- Increase read read counter by 2 and write counter by 1
- Continue the process till the loop counter AL value reaches 23 ( actual size of shellcode without encoding )
- Once the value exceeds 23 it will jump to return_shellcode location
- return_shellcode with stack implementation is to get rid of NULL characters which was generating due to jmp shellcode instruction.
- Push the shellcode address onto the stack
- Jump to the address stored on the stack