import struct
from ctypes import *
from x64dbgpy import *



def fakeQuery():
    strAddr = pluginsdk.ReadDword(pluginsdk.GetESP()-0x18)
    url = ""
    while pluginsdk.ReadByte(strAddr) != 0x00:
        url += chr(pluginsdk.ReadByte(strAddr))
        strAddr += 1
    #print url
    resultData = ""
    if url in queries:
        resultData = queries[url]
    else:
        print("Didn't find requested url in queries")
        return -1
    #print resultData
    pluginsdk.SetEAX(0)
    struct_addr = pluginsdk.GetEBX()
    pluginsdk.WriteDword(struct_addr+0x18, 1)
    pluginsdk.WriteDword(struct_addr+0x1C, rel_Overwrite)
    resultData += "\x00\x00"
    for i,c in enumerate(resultData):
        pluginsdk.WriteByte(rel_Overwrite+i,ord(c))
    return 1
    
def overwriteIP():                
    fakeIP         = "127.0.0.1\x00"
    #get address parameter and replace with 127.0.0.1 (ESP+4)
    strAddr = pluginsdk.ReadDword(pluginsdk.GetESP()+0x4)
    for i,c in enumerate(fakeIP):
        pluginsdk.WriteByte(strAddr+i,ord(c))
    pluginsdk.Wait()
    pluginsdk.Run()
    
def overwriteRandom(fakeRandomData):
    pluginsdk.StepOut()
    pluginsdk.StepOver()
    strAddr = pluginsdk.ReadDword(pluginsdk.GetESP()-0x4)
    for i,c in enumerate(fakeRandomData):
        pluginsdk.WriteByte(strAddr+i,ord(c))
    pluginsdk.Run()
    pluginsdk.Wait()
    
f = open(r"D:\current\flareon2018\malware_skillz\parsedpcap.txt")
c = f.read()
f.close()



queries = {}
content = c.split("\n")
for c in content:
    c = c.split(" ")
    if len(c) == 2:
        queries[c[0]] = c[1]

pluginsdk.x64dbg.DbgCmdExec('bp kernel32.LoadLibraryA')
pluginsdk.Wait()
pluginsdk.Run()
pluginsdk.Wait()
pluginsdk.Run()
pluginsdk.Wait()
pluginsdk.Run()
pluginsdk.Wait()
pluginsdk.StepOut()
pluginsdk.StepOver()

rel_addr = pluginsdk.GetEIP()
rel_DnsQueryA = rel_addr + (0x026029C - 0x0260226)
rel_Wanted    = rel_addr + (0x02602ED - 0x0260226)
rel_Overwrite = rel_addr + (0x0260C00 - 0x0260226)

pluginsdk.SetBreakpoint(rel_DnsQueryA)
pluginsdk.SetBreakpoint(rel_Wanted)

pluginsdk.Run()

lastResult = 1
while pluginsdk.GetEIP() != rel_Wanted:
    lastResult = fakeQuery()
    if lastResult < 0: break
    pluginsdk.Run()
    pluginsdk.Wait()

for i in range(0x100):
    pluginsdk.WriteByte(rel_Overwrite+i,0x00)
    
pluginsdk.x64dbg.DbgCmdExec('deleteBPX kernel32.LoadLibraryA')

pluginsdk.x64dbg.DbgCmdExec('bp ws2_32.inet_addr')
pluginsdk.x64dbg.DbgCmdExec('bp ws2_32.recv')
pluginsdk.x64dbg.DbgCmdExec('bp ws2_32.send')
pluginsdk.x64dbg.DbgCmdExec('bp advapi32.CryptGenRandom')
pluginsdk.Run()
pluginsdk.Wait()
overwriteIP()
#normal connection
"""
overwriteRandom("\x0b\x7d\xbe\x80\xe7\xb8\x44\x1f\xf3\x05\x5c\xe8\xd0\x75\x7b\xcb" \
                "\xf4\x82\x41\x7f\x0d\x62\x1a\xac\x87\x11\x05\x49\x10\x22\x12\x5d" \
                "\xa9\xa2\xe4\x74\xeb\x8f\xe6\xba\x96\x41\xb2\x00\x30\xe8\xa8\x63")
"""
#packet 3793, package for smb connection
overwriteRandom("\xe7\x66\xe6\x5a\xe8\x50\x9d\x68\x33\xd7\x3a\x37\xd1\xec\x4a\xd8" \
                "\x18\x99\x19\xa5\x40\x2f\x80\x15\x31\xe9\x36\xd1\x32\xe5\xdf\x42" \
                "\xf2\x2f\x99\xc8\xdb\x9f\xfe\x67\x3a\x03\x52\xc5\x8d\x79\x99\xc4")
                
pluginsdk.x64dbg.DbgCmdExec('bp ntdll.wcscmp')
pluginsdk.x64dbg.DbgCmdExec('bp ntdll.wcsncpy')
pluginsdk.x64dbg.DbgCmdExec('bp ntdll.wcscat')
pluginsdk.x64dbg.DbgCmdExec('deleteBPX '+hex(rel_DnsQueryA))
pluginsdk.x64dbg.DbgCmdExec('deleteBPX '+hex(rel_Wanted))
#send
pluginsdk.Run()
#recv
pluginsdk.Run()
pluginsdk.Run()
pluginsdk.Run()
#wcscmp
pluginsdk.Run()

#cd 54 02 1b 32 b1 ca

#till here for manual

#pluginsdk.x64dbg.DbgCmdExec('deleteBPX ntdll.wcscmp')
#pluginsdk.x64dbg.DbgCmdExec('deleteBPX ntdll.wcsncpy')
#pluginsdk.x64dbg.DbgCmdExec('deleteBPX ntdll.wcscat')
#pluginsdk.x64dbg.DbgCmdExec('deleteBPX ws2_32.inet_addr')
    
"""
named_index = 0
for i in range(200):
    allocated = []
    pluginsdk.Run() #gen random
    pluginsdk.Wait()
    pluginsdk.x64dbg.DbgCmdExec('bp kernel32.LocalAlloc')
    pluginsdk.Run() #send

    while pluginsdk.ReadDword(pluginsdk.GetESP()+0x4) != 0:
        pluginsdk.Run() #recv
        pluginsdk.Wait()
        pluginsdk.Run() #LocalAlloc of recv
        pluginsdk.Wait()
        
    while pluginsdk.ReadDword(pluginsdk.GetESP()+0x4) == 0:
        amount = pluginsdk.ReadDword(pluginsdk.GetESP()+0x8)
        pluginsdk.StepOut()
        pluginsdk.StepOver()
        pluginsdk.Wait()
        bufferAddr = pluginsdk.GetEAX()
        print hex(bufferAddr)
        pluginsdk.Run()
        pluginsdk.Wait()
        allocated.append((bufferAddr, amount))
    #at crypt gen random
    pluginsdk.x64dbg.DbgCmdExec('deleteBPX kernel32.LocalAlloc')
    for ind, entry in enumerate(allocated):
        data  = ""
        index = 0x1C
        for i in range(entry[1]-0x1C):
            data += chr(pluginsdk.ReadByte(entry[0]+index+i))
        f = open(r"D:\current\flareon2018\malware_skillz\packet\dump_"+str(named_index)+r"_"+str(ind)+r".txt","wb")
        f.write(data)
        f.close()
    named_index +=1
"""
