In this part, we will try to push a value on to the stack and will try to read it. We will

assembly code

mov eax, 0xdead
mov ebx, 0xbeef
push eax
push ebx

We get the below raw bytes (there are various websites from which you can do this, if you do not know how to generate the raw bytes.):

B8ADDE0000BBEFBE00005053

Now we will try to execute the code below and try to read the values found in the register:

# testing for stack
from qiling import Qiling
from qiling.const import QL_VERBOSE

shellcode = bytes.fromhex('''B8ADDE0000BBEFBE00005053''')
ql = Qiling(code=shellcode, archtype='x86', ostype='Linux', verbose=QL_VERBOSE.DISASM)
ql.run()

hex(ql.arch.regs.eax)
hex(ql.arch.regs.ebx)
ql.log.info("stack @ 0 : " + hex(ql.stack_read(0)))
ql.log.info("stack @ 4 : " + hex(ql.stack_read(4)))
ql.stop()

Output:

[+] 	Profile: default
[+] 	Mapping GDT at 0x30000 with limit 0x1000
[=] 	011ff000 [[shellcode_stack]    + 0x1ff000]  b8 ad de 00 00       mov                  eax, 0xdead
[=] 	011ff005 [[shellcode_stack]    + 0x1ff005]  bb ef be 00 00       mov                  ebx, 0xbeef
[=] 	011ff00a [[shellcode_stack]    + 0x1ff00a]  50                   push                 eax
[=] 	011ff00b [[shellcode_stack]    + 0x1ff00b]  53                   push                 ebx
[+] 	
[+] 	syscalls called
[+] 	------------------------
[+] 	
[+] 	strings ocurrences
[+] 	------------------------
[=] 	stack @ 0 : 0xbeef
[=] 	stack @ 4 : 0xdead

search for the string in the memory

# search for string in stack
from qiling import Qiling
from qiling.const import QL_VERBOSE

shellcode = bytes.fromhex('''B8ADDE0000BBEFBE00005053''')
ql = Qiling(code=shellcode, archtype='x86', ostype='Linux', verbose=QL_VERBOSE.DISASM)
ql.run()
res = ql.mem.search(needle=b'\xad\xde')
for i in res:
    h=hex(i)
			print(h)
    ql.mem.read(h, 32)
ql.mem.read(0x11feff8, 32)

We will see from the code that this pattern can be found three(3) times which is bit unusual.

0x11feff8
0x11feffc
0x11ff001

The output of this is

In [30]: ql.mem.read(0x11feff8, 32)
Out[30]: bytearray(b'\xad\xde\x00\x00\xad\xde\x00\x00\xb8\xad\xde\x00\x00\xbb\xef\xbe\x00\x00PS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

As we can see that there are multiple cases where we can see that deadbeef is found. !!!

finding what why multiple deadbeef is seen

Now I will use only one register and perform the movement to stack. We will then use the xor operation to clearout the value in the register.

I was able to perform the search and find the string but interestingly, I did find it in multiple places.

mov eax, 0xdead
push eax
mov eax, 0xbeef
push eax
xor eax,eax

If we convert this into raw hex we get the following.

B8ADDE000050B8EFBE00005031C0

We can use the code below to push data onto the stack.

from qiling import Qiling
from qiling.const import QL_VERBOSE

def main():
    shellcode = bytes.fromhex('''B8ADDE000050B8EFBE00005031C0''')
    ql = Qiling(code=shellcode, archtype='x86', ostype='Linux', verbose=QL_VERBOSE.DISASM)
    ql.run()

    print_mem(ql, b'\xad\xde')
    ql.stop()

def print_mem(ql:Qiling , sarch: bytearray):
    res = ql.mem.search(needle=sarch)
    dist = 0
    fst = None
    for i in res:
        if(fst == None):
            fst = i
        else:
            dist = i - fst
        print(hex(i) + " + " + hex(dist) + " => " , end='')       
        print(ql.mem.read(i, 16))

main()

Output:

[+] 	strings ocurrences
[+] 	------------------------
0x11feffc + 0x0 => bytearray(b'\xad\xde\x00\x00\xb8\xad\xde\x00\x00P\xb8\xef\xbe\x00\x00P')
0x11ff001 + 0x5 => bytearray(b'\xad\xde\x00\x00P\xb8\xef\xbe\x00\x00P1\xc0\x00\x00\x00')

interestingly we can now see out search strings here as well.