[
  {
    "path": ".gitmodules",
    "content": "[submodule \"standalone/RevealPE\"]\n\tpath = standalone/RevealPE\n\turl = https://github.com/vallejocc/RevealPE.git\n[submodule \"IDA/IdaDiscover\"]\n\tpath = IDA/IdaDiscover\n\turl = https://github.com/vallejocc/idaDiscover.git\n"
  },
  {
    "path": "IDA/readme.md",
    "content": "\n# set_symbols_for_addresses\n\nThis scripts asks you for a file containing pairs address - symbol. It walks all segments searching for DWORDs matching the addresses of the given file of pairs address - symbols, and it will name the variable containing the address with the symbol name. This script is thought to be used together with the windbg script dump_process_symbols_to_file.wdbg.\n\n# stack_strings_deobfuscator_1\n\nSome malware families construct strings into the stack, like this:\n\n            mov     dword ptr [ebp-18h], 61737376h ; vssa\n            mov     dword ptr [ebp-14h], 642E6970h ; pi.d\n            mov     word ptr [ebp-10h], 6C6Ch; ll\n\nIn addition, i have found malware families permutating code (they split the code in portions and the mix these portions, \nadding jumps from a portion to the next one for getting the code being executed in the correct order), and constructing\nstrings in stack, for example:\n\n            loc_4751A4:\n              nop\n              mov     dword ptr [ebp-18h], 61737376h ; vssa\n              nop\n              jmp     loc_474E10                            \n                |\n                v                        \n            loc_474E10:\n              nop\n              mov     dword ptr [ebp-14h], 642E6970h ; pi.d\n              nop\n              jmp     loc_475532            \n                |\n                v            \n            loc_475532:\n              mov     word ptr [ebp-10h], 6C6Ch; ll\n              jmp     loc_4750C3\n\nThis script add coments at points of code where each part of the string is being reconstructed. In addition it tries to\nconstruct for each function the string being constructed into the function. For this purpose, it needs to follow basic\nblocks of each funcion in the same order that they are going to be executed (in this way the strings will be reconstructed\nin the same order in spite of the fact the code is permutated). When it constructs an string, the output is like this:\n\n   \"Function text constructed in stack: sub_474CA0 |     vssapi.dllCreateVssBackupComponentsInternaVssFreeSnapshotPropertiesInternaupComponents@@@Zonents@@YGJPAPAVIVssBackreeSnapshotPropertiessBackupCompateVVssF?Cre\"\n\n"
  },
  {
    "path": "IDA/set_symbols_for_addresses.py",
    "content": "################################################\n##\n## Author: Javier Vicente Vallejo\n## Twitter: @vallejocc\n## Web: http://www.vallejo.cc\n##\n################################################\n#\n#  This scripts asks you for a file containing pairs address - symbol.\n#  \n#  This script walks all segments searching for DWORDs matching the addresses of the given file of pairs address - symbols,\n#  and it will name the variable containing the address with the symbol name.\n#\n#  This script is thought to be used together with the windbg script dump_process_symbols_to_file.wdbg.\n#\n################################################\n\nimport idaapi\nimport idc\nimport idautils\nimport tkFileDialog\n\n################################################\n\ndef binarySearch(alist, item):\n    first = 0\n    last = len(alist)-1\n    found = False\n    retval = 0  \n    while first<=last and not found:\n        midpoint = (first + last)//2\n        #algunos malware saltan al comienzo de la api mas algunas instrucciones, por ejemplo:\n        #ADVAPI32!RegDeleteValueW:\n        #77daedf1 8bff            mov     edi,edi\n        #77daedf3 55              push    ebp\n        #77daedf4 8bec            mov     ebp,esp\n        #77daedf6 83ec0c          sub     esp,0Ch <- malware salta aqui y ejecuta el push ebp, mov ebp, esp en su codigo\n        #Por eso no comparamos la direccion dada con la de la lista, sino que aceptamos q sea la de la lista o hasta 10 posiciones mas alante\n        if alist[midpoint][0] <= item and item < alist[midpoint][0]+10: \n            found = True\n            retval = midpoint\n        else:\n            if item < alist[midpoint][0]:\n                last = midpoint-1\n            else:\n                first = midpoint+1    \n    return found, retval\n\n################################################\n\nsymbols = []\n\nimagebase = idaapi.get_imagebase()\nea = here()\nsymbols_file_path = tkFileDialog.askopenfilename()\n\nf = open(symbols_file_path, \"r+b\")\nlines = f.readlines()\nf.close()\n\n\n##### Collect symbols by content and set symbols by rva\n\nfor line in lines:\n    print line\n    linesplit = line.split(\"          \")\n    if len(linesplit)>0:\n        symbolstr = linesplit[1].strip()\n        symbolstr = symbolstr.replace(\" = <no type information>\", \"\").replace(\"(<no parameter info>)\", \"\").replace(\"__CARRIAGE_RETURN__\", \"\\r\").replace(\"__NEWLINE__\", \"\\n\")\n        if \" byrva\" in symbolstr:            \n            symbolstr = symbolstr.replace(\" byrva\", \"\")\n            if \" comment\" in symbolstr:\n                symbolstr = symbolstr.replace(\" comment\", \"\")\n                MakeComm(imagebase+int(linesplit[0],16), symbolstr)\n            elif \" rptcomment\" in symbolstr:\n                symbolstr = symbolstr.replace(\" rptcomment\", \"\")\n                MakeRptCmt(imagebase+int(linesplit[0],16), symbolstr)\n            else:\n                MakeNameEx(imagebase+int(linesplit[0],16), symbolstr.replace(\"!\", \"_\").replace(\" \", \"\"), 0)\n        else:\n            symbol = (int(linesplit[0],16), symbolstr)\n            symbols.append(symbol)\n\n##### Set symbols by content\n\nif len(symbols):\n    \n    symbols = sorted(symbols, key=lambda symbols: symbols[0])\n    \n    for seg_ea in Segments():\n    \n        for ea in range(seg_ea, SegEnd(seg_ea)):\n            \n            vop1 = None\n            vop2 = None\n            \n            bIsCode = isCode(GetFlags(ea))\n                    \n            if bIsCode:\n                op1type = idc.GetOpType(ea, 0)\n                op2type = idc.GetOpType(ea, 1)\n                if op1type == 5 or op1type == 6 or op1type == 7:\n                    vop1 = GetOperandValue(ea,0)\n                if op2type == 5 or op2type == 6 or op2type == 7:\n                    vop2 = GetOperandValue(ea,1)\n                           \n            v = Dword(ea)\n            \n            isymbol = binarySearch(symbols, v)\n            if vop1 and not isymbol[0]: isymbol = binarySearch(symbols, vop1)\n            if vop2 and not isymbol[0]: isymbol = binarySearch(symbols, vop2)\n            \n            if isymbol[0]:\n                \n                i = isymbol[1]\n                \n                if bIsCode:\n                    print \"Is code!! %x %s\\n\" % (ea, symbols[i][1])\n                    MakeComm(ItemHead(ea),symbols[i][1])\n                else:\n                    print \"%x %s\\n\" % (ea, symbols[i][1])\n                    MakeUnkn(ea,4)\n                    MakeDword(ea)\n                    MakeNameEx(ea,symbols[i][1].replace(\"!\", \"_\").replace(\" \", \"\"),0)\n                    MakeComm(ea,symbols[i][1])\n                \n                symbols[i] = (symbols[i][0], \"_\"+symbols[i][1])\n\n################################################        \n\n\n"
  },
  {
    "path": "IDA/stack_strings_deobfuscator_1.py",
    "content": "################################################\n##\n## Author: Javier Vicente Vallejo\n## Twitter: @vallejocc\n## Web: http://www.vallejo.cc\n##\n################################################\n## \n## Some malware families construct strings into the stack, like this:\n## \n##             mov     dword ptr [ebp-18h], 61737376h ; vssa\n##             mov     dword ptr [ebp-14h], 642E6970h ; pi.d\n##             mov     word ptr [ebp-10h], 6C6Ch; ll\n## \n## In addition, i have found malware families permutating code (they split the code in portions and the mix these portions, \n## adding jumps from a portion to the next one for getting the code being executed in the correct order), and constructing\n## strings in stack, for example:\n## \n##             loc_4751A4:\n##               nop\n##               mov     dword ptr [ebp-18h], 61737376h ; vssa\n##               nop\n##               jmp     loc_474E10                            \n##                 |\n##                 v                        \n##             loc_474E10:\n##               nop\n##               mov     dword ptr [ebp-14h], 642E6970h ; pi.d\n##               nop\n##               jmp     loc_475532            \n##                 |\n##                 v            \n##             loc_475532:\n##               mov     word ptr [ebp-10h], 6C6Ch; ll\n##               jmp     loc_4750C3\n## \n## This script add coments at points of code where each part of the string is being reconstructed. In addition it tries to\n## construct for each function the string being constructed into the function. For this purpose, it needs to follow basic\n## blocks of each funcion in the same order that they are going to be executed (in this way the strings will be reconstructed\n## in the same order in spite of the fact the code is permutated). When it constructs an string, the output is like this:\n## \n##    \"Function text constructed in stack: sub_474CA0 |     vssapi.dllCreateVssBackupComponentsInternaVssFreeSnapshotPropertiesInternaupComponents@@@Zonents@@YGJPAPAVIVssBackreeSnapshotPropertiessBackupCompateVVssF?Cre\"\n##\n## Other malware constructs strings on the stack by moving each byte to the stack, like this:\n##\n##    mov     [ebp+var_30], 48h\n##    mov     [ebp+var_2F], 65h\n##    mov     [ebp+var_2E], 6Ch\n##    mov     [ebp+var_2D], 6Ch\n##    mov     [ebp+var_2C], 6Fh\n##\n## For this cases i recommend to you to read this article (with ida script included):\n##\n##    https://www.fireeye.com/blog/threat-research/2014/08/flare-ida-pro-script-series-automatic-recovery-of-constructed-strings-in-malware.html\n##\n################################################\n\nimport idaapi\nimport idc\nimport idautils\n\nloutput = []\n\nfor segea in Segments():    \n\n    for funcea in Functions(SegStart(segea), SegEnd(segea)):        \n        \n        functxt = \"\"\n        \n        functionName = GetFunctionName(funcea)\n        \n        #print \"Current function: %s\" % functionName\n        \n        f = idaapi.get_func(funcea)\n        fc = idaapi.FlowChart(f)\n        lblocks = []\n        \n        for block in fc:            \n            lblocks.append(block)\n        \n        lorderedblocks = []\n        \n        while len(lblocks):\n            first = lblocks.pop(0)\n            lorderedblocks.append(first)                        \n            for head in Heads(first.startEA, first.endEA):\n                ins = GetMnem(head)\n                if len(ins) and ins[0]=='j':\n                    op0 = GetOpType(head, 0)\n                    if op0==5 or op0==6 or op0==7:\n                        v = GetOperandValue(head, 0)\n                        for i in range(0, len(lblocks)):\n                            if v == lblocks[i].startEA: \n                                #print \"Moving block %x:%x\" % (head, v)\n                                lblocks.insert(0, lblocks.pop(i))\n                                break\n                                        \n        for block in lorderedblocks:\n            for head in Heads(block.startEA, block.endEA):     \n                dism = GetDisasm(head)\n                if \"mov     dword ptr [ebp\" in dism or \"mov     word ptr [ebp\" in dism:\n                    op1 = GetOpType(head, 1)\n                    if op1==5 or op1==6 or op1==7:                        \n                        v = GetOperandValue(head, 1)\n                        curtxt = None\n                        if (\"mov     dword ptr [ebp\" in dism) and v>0xffffff:\n                            curtxt = chr(v&0xff) + chr((v&0xff00)>>8) + chr((v&0xff0000)>>16) + chr((v&0xff000000)>>24)\n                        if (\"mov     word ptr [ebp\" in dism) and v>0xff:\n                            curtxt = chr(v&0xff) + chr((v&0xff00)>>8)\n                        if curtxt:                            \n                            print hex(head), \":\", GetDisasm(head), \"--->\", curtxt\n                            MakeRptCmt(head, curtxt)\n                            functxt += curtxt\n                            \n        if len(functxt):\n            loutput.append(\"Function text constructed in stack: \" + functionName + \" |     \" + functxt)\n\nfor e in loutput:\n    print e\n\n                    \n            \n                        "
  },
  {
    "path": "README.md",
    "content": "Useful Scripts for helping in reverse engeenering.\n"
  },
  {
    "path": "WinDbg/Readme.md",
    "content": "\n$$>a<dump_injected_pe_rwemem.wdbg <destination directory>\n--------------------------------------------------------\n\nThis windbg script will walk the results of !address command for each process in the debuggee machine, \nsearching for RWE memory containing PE files (based on the analysis of PE header). \n \nWhen a PE file in RWE memory is found, the script will dump it. In addition to dump it, it will fix \nsome fields of PE header: imagebase will be set to the address where the PE is loaded, and \nsection[i].PointerToRawData = section[i].VirtualAddress (because we are dumping a mapped PE to disk and,\nif we want to analyze the dumped PE with a disassembler for example, we need to fix the sections).\n\nArticle talking about this script: https://vallejo.cc/2017/08/13/tools-for-unpacking-malware-part-1-dumping-executables-from-rwe-memory/\n\n$$>a<dump_injected_pe_rwemem_fast.wdbg  <destination directory>\n---------------------------------------------------------------\n\nThis windbg script will walk the results of !address command for each process in the debuggee machine, \nsearching for RWE memory containing PE files (based on the analysis of PE header). \n\nWhen a PE file in RWE memory is found, the script will dump it. In addition to dump it, it will fix \nsome fields of PE header: imagebase will be set to the address where the PE is loaded, and \nsection[i].PointerToRawData = section[i].VirtualAddress (because we are dumping a mapped PE to disk and,\nif we want to analyze the dumped PE with a disassembler for example, we need to fix the sections).\n\nThe difference with the script dump_injected_pe_rwemem.wdbg (the non fast version) it is this script is\nnot paging-in each page before trying to dump a PE file. Usually pages will be there, but it could fail\nto dump the entire file if a page is not mapped.\n\nAnyway, for debugging, i recommend to disable swapping, for having pages always in memory.\n\nArticle talking about this script: https://vallejo.cc/2017/08/13/tools-for-unpacking-malware-part-1-dumping-executables-from-rwe-memory/\n\n$$>a<find_injected_pe_rwemem.wdbg\n---------------------------------\n\nThis windbg script will walk the results of !address command for each process in the debuggee machine, \nsearching for RWE memory containing PE files (based on the analysis of PE header). \n\nArticle talking about this script: https://vallejo.cc/2017/08/13/tools-for-unpacking-malware-part-1-dumping-executables-from-rwe-memory/\n\n$$>a<anti_antidebug_rdtsc.wdbg\n------------------------------\n\nThis script works in similar way than anti-rdtsc tools that install a driver.\n  \nThe script enables flag 2 of cr4: TSD Time Stamp Disable. In this way rdtsc is a privileged instruction. \nAfter that, it enables the option  for stopping when user mode exception (gflag +sue +soe, gflags 0x20000001).\nThen we enable 0xc0000096 -> privileged instruction.    \nIn this way, when rdtsc is executed by an application, an exception will occur and windbg will catch the exception.\nIn that moment, the script checks the ins code of rdtsc, 0x310f. If it is a rdtsc instruction, it skips \nthe instruction ip = ip+2.\nFinally it sets edx = 0, and eax = last_counter+1.\nApplications execution rdtsc will see an increment of 1 each rdtsc execution.\n\n$$>a<change_object_name.wdbg <full object path + name>                                                                                              \n------------------------------------------------------\n\ni.e. pafish tries to open vmware devices \"\\\\\\\\.\\\\HGFS\" and \"\\\\\\\\.\\\\vmci\", \nif can use this script to rename these devices in this way:           \n                                                                                                                                                   \nchange_object_name.wdbg \\\\global??\\\\hgfs  (in this case we rename the symboliclink)   \\\\global??\\\\hgfs -> \\\\global??\\\\agfs                  \nchange_object_name.wdbg \\\\devices\\\\vmci   (in this case we rename the deviceobject)   \\\\devices\\\\vmci -> \\\\devices\\\\amci                    \n                                                                                                                                                    \nThe script changes the first letter of the name (setting 'a'). \nIf you need other letter or additional modifications, it is easy to modify the script.\n\n$$>a<change_process_name.wdbg <main module of the process to be renamed>\n------------------------------------------------------------------------\n\ni.e. if we want to rename vmtoolsd.exe:\n\n$$>a<change_process_name.wdbg vmtoolsd.exe   ->  it will rename the process to vmtoolse\n\nThe script increase +1 the last letter of the name. If you need other or additional modifications, \nit is easy to modify the script.\n  \n$$>a<dump_process_symbols_to_file.wdbg <path> <proc>                                                                                                 \n----------------------------------------------------  \n  \nThis simple script will dump to a file all the symbols of the given process.                                                                         \nIf you dump a PE from memory, it could have variables pointing to symbols (for example, api \naddresses that it got with GetProcAddress, etc...).      \nIt is useful to have a list of pairs (symbol, address) because in this way if we open the \ndumped PE with IDA we can search for that addresses and set a name for the variable containing them.\n\nArticle talking about this script: https://vallejo.cc/2017/08/13/tools-for-unpacking-malware-part-1-dumping-executables-from-rwe-memory/\n\n$$>a<load_code_to_kernel_memory.wdbg <src code> <mem size> <offset start routine>\n---------------------------------------------------------------------------------\n\nAllocates kernel memory and load a block of data to that kernel memory. Later it creates a kernel thread\nstarting to run on the given offset.\n\n$$>a<log_processes.wdbg <destination directory>\n-----------------------------------------------\n\nLog running processes to a given file.\n\n$$>a<pagein_range.wdbg <start_address> <end_address> <process>\n--------------------------------------------------------------\n\nPage into memory a range of memory of the given process.\n\n$$>a<search_bytes_all_processes.wdbg <byte1> <byte2> ... <byteN>       (max 16 bytes)\n-------------------------------------------------------------------------------------\n\nThis script is useful for search a max of 16 given bytes through all the running processes.\n\n$$>a<search_string_target_process.wdbg <proc> <byte1> <byte2> .. <byteN>\n------------------------------------------------------------------------\n\nThis script is useful for search a max of 16 given bytes in the given process.\n\n$$>a<search_string_all_processes.wdbg <string>\n----------------------------------------------\n\nThis script is useful for search a given string through all the running processes.\n  \n$$>a<search_string_target_process.wdbg <proc> <string> \n-----------------------------------------------------\n\nThis script is useful for search a given string in a given process.\n\n$$>a<secure_writemem.wdbg <start> <end> <process> <targetdir> <ext>\n-------------------------------------------------------------------\n\nthis script tries to dump a range of memory. \nIf its not possible to dump a part of the range, that part if filled with random data\n(really its filled with \"\\x11\\x11\\x11......\\x11\\x20\\x0d\\x0a\" (total length 0x1000 for each page filled), \nbut we must not assume it will always contain this value.\n\n$$>a<show_address_info.wdbg <address> <process>\n-----------------------------------------------\n\nShow info about a given address of a given process.\n\n$$>a<show_proc_from_handle.wdbg <handle>\n----------------------------------------\n\nShow a process info from a given handle.\n\n$$>a<symbols.wdbg\n-----------------\n\nLoad symbols.\n\n\n"
  },
  {
    "path": "WinDbg/anti_antidebug_rdtsc.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$  $$>a<anti_antidebug_rdtsc.wdbg\n$$\n$$  This script works in similar way than anti-rdtsc tools that install a driver.\n$$  \n$$  The script enables flag 2 of cr4: TSD Time Stamp Disable. In this way rdtsc is a privileged instruction. \n$$  After that, it enables the option  for stopping when user mode exception (gflag +sue +soe, gflags 0x20000001).\n$$  Then we enable 0xc0000096 -> privileged instruction.    \n$$  In this way, when rdtsc is executed by an application, an exception will occur and windbg will catch the exception.\n$$  In that moment, the script checks the ins code of rdtsc, 0x310f. If it is a rdtsc instruction, it skips the instruction ip = ip+2.\n$$  Finally it sets edx = 0, and eax = last_counter+1.\n$$  Applications execution rdtsc will see an increment of 1 each rdtsc execution.\n$$\n\n\n$$set rdtsc as priv instruction, then catch exceptions for priv instructions and skip rdtsc(eip=eip+2) and set edx:eax = last rdtsc returned value +1\n$$use $t9 for counter\nr $t9 = 0\n$$rdtsc = privileged instruction\nr cr4 = cr4 | 4\n$$Stop on exception\n!gflag +soe\n$$Stop on unhandled user-mode exception\n!gflag +sue\n$$disable access violation (we have enabled exception in user mode, and access violation will cause lot of exceptions)\nsxd av\n$$we enable to catch privileged instructions execution (we have converted rdtsc in priv ins with cr4)\n$$in this moment we check if it is rdtsc, and in this case, we jump over the instruction and we set eax=0 edx=0\nsxe -c \".if((poi(eip)&0x0000ffff)==0x310f){.printf \\\"rdtsc\\r\\n\\\";r eip = eip+2;r eax=@$t9;r edx=0;r $t9=@$t9+1; gh;}\" c0000096"
  },
  {
    "path": "WinDbg/break_each_new_process.wdbg",
    "content": "\n\n$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<break_each_new_process.wdbg\n$$\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*https://msdl.microsoft.com/download/symbols;SRV*c:\\symcache*https://chromium-browser-symsrv.commondatastorage.googleapis.com;SRV*c:\\symcache\\*https://symbols.mozilla.org/\";\n    .reload\n}\n\nba e1 MmCreateProcessAddressSpace"
  },
  {
    "path": "WinDbg/change_object_name.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$  $$>a<change_object_name.wdbg <full object path + name>\n$$\n$$      i.e. pafish tries to open vmware devices \"\\\\\\\\.\\\\HGFS\" and \"\\\\\\\\.\\\\vmci\", if can use this script to rename these devices in this way:\n$$\n$$          change_object_name.wdbg \\\\global??\\\\hgfs  (in this case we rename the symboliclink)   \\\\global??\\\\hgfs -> \\\\global??\\\\agfs\n$$          change_object_name.wdbg \\\\devices\\\\vmci   (in this case we rename the deviceobject)   \\\\devices\\\\vmci -> \\\\devices\\\\amci\n$$\n$$  The script changes the first letter of the name (setting 'a'). If you need other letter or additional modifications, it is easy to modify the script\n$$\n\naS stage @$t19\naS x64arch $t18\naS objhnameinfodisp $t17\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    $$is x64?\n    r x64arch = 0; \n    r objhnameinfodisp = 0x10;\n    .foreach( tok { .effmach } ) \n    {\n        .if($scmp(\"${tok}\",\"x64\")==0)\n        {\n            r x64arch = 1;\n            r objhnameinfodisp = 0x20;\n            .break;\n        };\n    };\n}\n\nr stage = 0\n\n.foreach( tok { !object \"${$arg1}\" } )\n{\n    .printf \"${tok}\\r\\n\"    \n\n    .if(${stage}==1)\n    {\n        .echo ${tok}\n        dt _OBJECT_HEADER ${tok}        \n        r $t0 = ${tok}        \n        dt _OBJECT_HEADER_NAME_INFO (@$t0-${objhnameinfodisp})\n        $$ $t0 -> OBJECT_HEADER_NAME_INFO\n        r $t0 = @$t0 - ${objhnameinfodisp}\n        $$ $t0 -> OBJECT_HEADER_NAME_INFO.UNICODE_STRING\n        r $t0 = @$t0 + @@c++(#FIELD_OFFSET(_OBJECT_HEADER_NAME_INFO, Name))\n        $$ $t0 -> OBJECT_HEADER_NAME_INFO.UNICODE_STRING.Buffer\n        r $t0 = @$t0 + @@c++(#FIELD_OFFSET(_UNICODE_STRING, Buffer))\n        db poi $t0\n        $$change the first letter for 'a'\n        eb (poi $t0) 'a'\n        .printf \"--------------------\\r\\n\"\n        db poi $t0\n        .break\n    }    \n    \n    .if(${stage}==0)\n    {\n        .if($scmp(\"${tok}\",\"ObjectHeader:\")==0)\n        {\n            r stage = 1\n        }\n    }\n}\n\n"
  },
  {
    "path": "WinDbg/change_process_name.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$  $$>a<change_process_name.wdbg <main module of the process to be renamed>\n$$\n$$  i.e. if we want to rename vmtoolsd.exe:\n$$\n$$      $$>a<change_process_name.wdbg vmtoolsd.exe   ->  it will rename the process to vmtoolse\n$$\n$$  The script increase +1 the last letter of the name. If you need other or additional modifications, it is easy to modify the script\n\n.logopen ${$arg2}\\change_process_name.start\n.printf \"start\"\n.logclose\n\naS stage @$t19\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    r stage = 2\n    \n    .printf \"xxxx\"\n    \n    .foreach (processes_tok { !process /m ${$arg1} 0 0 })\n    {\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Renaming process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n\n            r $t4 = ${processes_tok}\n            \n            r $t0 = @@c++( ( ( nt!_EPROCESS * ) @$t4 )->SeAuditProcessCreationInfo.ImageFileName )\n            r $t1 = (poi @$t0)&0xffff\n            r $t2 = (poi (@$t0+2))&0xffff\n            r $t3 = (poi (@$t0+@@c++(#FIELD_OFFSET(nt!_UNICODE_STRING, Buffer))))\n            db ($t3 + $t1 - a)\n            $$go to end of buffer of _UNICODE_STRING, and go back 0xa bytes. For example <filepath....><lastbyte>.exe. We locate on lastbyte, and we increase 1 the value of last byte\n            $$For example <fullpath>\\vmtoolsd.exe, will be modified to <fullpath>\\vmtoolse.exe\n            eb ($t3 + $t1 - a) ((poi($t3 + $t1 - a)&0xff)+1)\n            \n            !process @$t4 0\n            \n        }\n    }\n}\n\n.logopen ${$arg2}\\change_process_name.end\n.printf \"end\"\n.logclose\n"
  },
  {
    "path": "WinDbg/dump_injected_pe_rwemem.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$ $$>a<dump_injected_pe_rwemem.wdbg <destination directory>\n$$\n$$ This windbg script will walk the results of !address command for each process in the debuggee machine, \n$$ searching for RWE memory containing PE files (based on the analysis of PE header). \n$$ \n$$ When a PE file in RWE memory is found, the script will dump it. In addition to dump it, it will fix \n$$ some fields of PE header: imagebase will be set to the address where the PE is loaded, and \n$$ section[i].PointerToRawData = section[i].VirtualAddress (because we are dumping a mapped PE to disk and,\n$$ if we want to analyze the dumped PE with a disassembler for example, we need to fix the sections).\n$$\n\n$$.sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n$$.reload\n\n.logopen ${$arg1}\\dump_injected_pe_rwemem.start\n.printf \"start\"\n.logclose\n\naS stage @$t19\naS temp @$t18\naS temp2 @$t17\naS temp3 @$t16\naS isPossiblePE @$t15\naS isDosMessageBased @$t14\naS pe @$t13\naS fileheader @$t12\naS optionalheader @$t11\naS sections @$t10\naS nsections @$t9\naS lastsect @$t8\naS prev1 @$t7\naS prev2 @$t6\naS baseaddr @$t5\naS baseaddrlen @$t4\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    r stage = 2\n    \n    .printf \"xxxx\"\n    \n    .foreach (processes_tok { !process 0 0 })\n    {\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Analyzing process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n        \n            .process /i ${processes_tok}\n            g\n            \n            .block\n            {\n                .reload /user\n            }\n            \n            $$search for memory blocks with ReadWriteExecute protection\n            \n            $$careful:\n            $$ when the baseaddress is over 0x10000000 findstr tokens will be:\n            $$ 93:7640:20010000\n            $$ 2002c000\n            $$ 1c000\n            $$ UserRange\n            $$ ...\n            $$ however if the addess is under 0x10000000:\n            $$ 25:1364:\n            $$ 60000\n            $$ 61000\n            $$ 1000\n            $$ UserRange\n            $$ The reason for this its windbg puts spaces before the base address when it hasnt 8 characters to complete 8 characters, but if the address is\n            $$ ???????? then it doesnt put spaces. We need to have in mind both case, and this is the reason of the stages of the next code\n            $$\n            \n            .foreach (tok { .shell -ci \"!address\" findstr /N /O /R /C:\"UserRange.*ExecuteReadWrite\" /C:\"UserRange.*ReadWriteExecute\" })\n            {\n                r isPossiblePE = 0\n                r isDosMessageBased = 0\n                \n                .printf \"${tok}\\n\"\n                \n                .if($spat(\"${tok}\",\"*:*:*\")!=0)\n                {\n                    r stage = 1\n                }\n                .elsif(${stage}==1)\n                {\n                    r prev1 = ${tok}                \n                    r stage = 2\n                }\n                .elsif(${stage}==2)\n                {\n                    r prev2 = ${tok}                \n                    r stage = 3\n                }\n                .elsif(${stage}==3)\n                {\n                    .if($spat(\"${tok}\",\"*UserRange*\")!=0)\n                    {\n                        r baseaddr = prev1 - prev2\n                        r baseaddrlen = prev2\n                        r stage = 5\n                    }\n                    .else\n                    {\n                        r baseaddr = prev1\n                        r baseaddrlen = ${tok}\n                        r stage = 4\n                    }\n                }\n                .elsif(${stage}==4)\n                {\n                    r stage = 5\n                }\n                .elsif(${stage}==5)\n                {\n                    $$for each block with ReadWriteExecute protection, check MZ / PE\n                    \n                    r @$t0 = baseaddr\n                    \n                    .if(@$t0!=0)\n                    {\n                        .printf \"base %x\\n\", @$t0\n                        \n                        .pagein /p ${processes_tok} @$t0\n                        g\n                        \n                        $$!address @$t0\n                                \n                        .if($vvalid(@$t0, 2)==1)\n                        {\n                            .printf \"valid base address\\n\"\n                            \n                            .printf \"PE_header %x\\n\", @$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew)\n                                        \n                            .if($vvalid(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew), 2)==1)\n                            {\n                                .printf \"valid PE_header address\\n\"\n                                \n                                .if(wo(@$t0)==0x5a4d & dwo(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew))==0x454E)\n                                {\n                                    $$We can find MZ / NE  images, we ignore them\n                                }\n                                .elsif(wo(@$t0)==0x5a4d & dwo(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew))==0x4550)\n                                {\n                                    $$if MZ and PE signatures, valid pe header\n                                    .printf \"valid PE_header\\n\"\n                                    r isPossiblePE = 1\n                                }\n                                .else\n                                {\n                                    $$if not MZ or not PE signature, but msdos message is found, its a possible pe header\n                                    r temp = 0\n                                    .foreach (tok2 { s -a @$t0 L 0x80 \"This program cannot \" })\n                                    {\n                                        r temp = 1\n                                    }\n                                    .if(${temp}==1)\n                                    {\n                                        .printf \"possible pe header\\n\"\n                                        r isPossiblePE = 1\n                                        r isDosMessageBased = 1\n                                    }\n                                }\n                            }\n                            .else\n                            {\n                                .printf \"not valid PE_header address\\n\"\n                            }\n                        }\n                        .else\n                        {\n                            .printf \"not valid base address\\n\"\n                        }\n                        \n                        $$if we have found a possible PE in a memory zone with ReadWriteExecute protection, we will check if the base address is in the list of loaded module\n                        .if(${isPossiblePE}==1)\n                        {\n                            .printf \"is possible module %x\\n\", @$t0\n\n                            $$  r temp = 0\n                            $$  $$search for valid from \"is not valid address\"\n                            $$  .foreach (tok3 { .shell -ci \"!lmi @$t0\" findstr /N /O \"valid.address\" })\n                            $$  {\n                            $$      r temp = ${temp} + 1\n                            $$  }\n                            $$  .printf \"%x\\n\", ${temp}\n                            $$  \n                            $$  We are going to disable !lmi check. I have found malware that is unmapping\n                            $$  the main module of a executable when it does process hollowing, and it loads\n                            $$  its injected PE in that address. In this cases, !lmi is not answering not valid\n                            $$  address for that address. However !address command is containing the path\n                            $$  of the module (for example Section [\\Windows\\explorer.exe]) when the module is\n                            $$  a valid loaded module, and it wont contain the path when it is an injected module\n                            $$  in RWE mem. So, we will skip !lmi check, and we will check !address results\n                            $$ vvvvvvvv DISABLE !LMI CHECK vvvvvvvvv\n                            r temp = 4\n                            $$ ^^^^^^^^ DISABLE !LMI CHECK ^^^^^^^^^\n                            \n                            $$ \"is not valid address\" was found\n                            .if(${temp} > 3) \n                            {\n                                $$ there are some modules that !lmi command is answering: is not valid address, however they seems to be valid loaded modules (not interesing for us). \n                                $$ However if we consults information about the address with !address we find things as:  \n                                $$ Memory Usage:           Section [\\WINDOWS\\System32\\blablabla.mui] (it happens usually with .mui files, but not only with them\n                                $$ We will discard results of !address with .dll], .mui] and .exe]                        \n    \n                                r temp = 0                            \n                                .foreach (tok4 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.mui\\]\" })\n                                {\n                                    r temp = ${temp} + 1\n                                }\n    \n                                r temp2 = 0\n                                .foreach (tok5 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.dll\\]\" })\n                                {\n                                    r temp2 = ${temp2} + 1\n                                }\n    \n                                r temp3 = 0\n                                .foreach (tok6 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.exe\\]\" })\n                                {\n                                    r temp3 = ${temp3} + 1\n                                }\n    \n                                .printf \"search !address .mui %x\\n\", ${temp}\n                                .printf \"search !address .dll %x\\n\", ${temp2}\n                                .printf \"search !address .exe %x\\n\", ${temp3}\n    \n                                .if(${temp} < 4 and ${temp2} < 4 and ${temp3} < 4)\n                                {\n                                    .if(${isDosMessageBased}==0)\n                                    {\n                                        .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                        .printf /D \"<b>Process: ${processes_tok} base: %x -> Possible injected or unpacked PE</b>\\n\", @$t0\n                                        .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                    }\n                                    .else\n                                    {\n                                        .printf /D \"-------------------------------------------------------------------------------------------------------------------------------------\\n\"\n                                        .printf /D \"Process: ${processes_tok} base: %x -> Possible injected or unpacked PE, based on the dos header message: This program cannot...\\n\", @$t0\n                                        .printf /D \"--------------------------------------------------------------------------------------------------------------------------------------\\n\"                                    \n                                    }\n                                    \n                                    .printf \"xxxx1\\n\"\n                                                                        \n                                    r pe = @$t0 + poi(@$t0 + @@(#FIELD_OFFSET(nt!_IMAGE_DOS_HEADER, e_lfanew)))\n                                    \n                                    .printf \"xxxx2 %x\\n\", ${pe}\n                                    \n                                    r fileheader = ${pe} + @@(#FIELD_OFFSET(nt!_IMAGE_NT_HEADERS, FileHeader))\n                                    \n                                    .printf \"xxxx3 %x\\n\", ${fileheader}\n                                    \n                                    r optionalheader = ${pe} + @@(#FIELD_OFFSET(nt!_IMAGE_NT_HEADERS, OptionalHeader))\n                                    \n                                    .printf \"xxxx4 %x\\n\", ${optionalheader}\n                                    \n                                    r nsections = poi(${fileheader} + @@(#FIELD_OFFSET(nt!_IMAGE_FILE_HEADER, NumberOfSections )))&0xffff\n                                    \n                                    .printf \"xxxx5 %x\\n\", ${nsections}\n                                    \n                                    r sections = ${pe} + @@c++(sizeof(nt!_IMAGE_NT_HEADERS))\n                                    \n                                    .printf \"xxxx6 %x\\n\", ${sections}\n                                    \n                                    $$ reach the end of the PE file (last section rva + last section vsize)                            \n                                    r lastsect = ${sections} + ( ${nsections} - 1 ) * @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n                                    r @$t1 = @$t0 + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) ${lastsect} )->VirtualAddress ) + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) ${lastsect} )->Misc.VirtualSize )\n                                    r @$t2 = @$t0 + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) ${lastsect} )->VirtualAddress ) + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) ${lastsect} )->SizeOfRawData )\n                                    r @$t3 = @$t0\n                                    .if (@$t2 > @$t1) { r @$t1 = @$t2 } \n                                    \n                                    $$limit to dump = 0x100000 bytes\n                                    .if (@$t1-@$t0 > 0x100000) \n                                    {\n                                        r @$t1 = @$t0+0x100000\n                                    }\n                                    \n                                    .printf \"xxxx7\"\n                                    \n                                    $$ before dumping the PE, we are going to modify sections' raw offset = virtual address for coherency in the dumped PE when we analyze it with IDA or any other tool                                    \n                                    r $t2 = ${sections}\n                                    r lastsect = ${sections} + ( ${nsections} ) * @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n                                    \n                                    .while (@$t2 < ${lastsect})\n                                    {\n                                        ed (@$t2+@@( #FIELD_OFFSET(nt!_IMAGE_SECTION_HEADER, PointerToRawData))) @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->VirtualAddress)\n                                        .if( @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->SizeOfRawData) < @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->Misc.VirtualSize))\n                                        {\n                                            ed (@$t2+@@( #FIELD_OFFSET(nt!_IMAGE_SECTION_HEADER, SizeOfRawData))) @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->Misc.VirtualSize)\n                                        }\n                                        .else\n                                        {\n                                            ed (@$t2+@@( #FIELD_OFFSET(nt!_IMAGE_SECTION_HEADER, Misc))) @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->SizeOfRawData)\n                                        }\n                                        r $t2 = @$t2 + @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n                                    }\n                                    \n                                    $$update sizeofimage                                    \n                                    .block\n                                    {\n                                        ed (${optionalheader} + @@(#FIELD_OFFSET(nt!_IMAGE_OPTIONAL_HEADER, SizeOfImage))) (@$t1-@$t0)&0x7fffffff\n                                    }\n                                    \n                                    .printf \"xxxx8\"\n                                    \n                                    $$update imagebase\n                                    .block\n                                    {\n                                        ed (${optionalheader} + @@(#FIELD_OFFSET(nt!_IMAGE_OPTIONAL_HEADER, ImageBase))) ${baseaddr}\n                                    }\n                                    \n                                    .printf \"xxxx9\"\n                                    \n                                    .printf \"dumping file address start %x end %x\", @$t0, @$t1\n                                    \n                                    .while (@$t0 < @$t1)\n                                    {\n                                        .printf \"paging in: %x\\n\", @$t0\n                                        .pagein /p ${processes_tok} @$t0\n                                        g\n                                        r @$t0 = @$t0 + 0x1000;\n                                    };\n                                    \n                                    .foreach /pS 4 (baseaddr_tok { ? baseaddr })\n                                    {\n                                        .foreach /pS 4 (baseaddrlen_tok { ? baseaddrlen })\n                                        {\n                                            .printf \"${processes_tok}_${baseaddr_tok}_${baseaddrlen_tok}.pedmp\"\n                                            .writemem ${$arg1}\\${processes_tok}_${baseaddr_tok}_${baseaddrlen_tok}.pedmp @$t3 L (@$t1 - @$t3)\n                                        }\n                                    }\n                                }\n                            }           \n                        }\n                        \n                        r stage = 0\n                    }\n                }\n            }\n        \n            r stage = 0\n        }\n    }\n \n    .logopen ${$arg1}\\dump_injected_pe_rwemem.end\n    .printf \"end\"\n    .logclose\n    \n    ad stage\n    ad temp\n    ad temp2\n    ad temp3\n    ad isPossiblePE\n    ad isDosMessageBased\n    ad pe\n    ad fileheader\n    ad optionalheader\n    ad sections\n    ad nsections\n    ad lastsect\n    ad prev1\n    ad prev2\n    ad baseaddr\n    ad baseaddrlen\n}"
  },
  {
    "path": "WinDbg/dump_injected_pe_rwemem_fast.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$     $$>a<dump_injected_pe_rwemem_fast.wdbg  <destination directory>\n$$\n$$ This windbg script will walk the results of !address command for each process in the debuggee machine, \n$$ searching for RWE memory containing PE files (based on the analysis of PE header). \n$$ \n$$ When a PE file in RWE memory is found, the script will dump it. In addition to dump it, it will fix \n$$ some fields of PE header: imagebase will be set to the address where the PE is loaded, and \n$$ section[i].PointerToRawData = section[i].VirtualAddress (because we are dumping a mapped PE to disk and,\n$$ if we want to analyze the dumped PE with a disassembler for example, we need to fix the sections).\n$$\n$$ The difference with the script dump_injected_pe_rwemem.wdbg (the non fast version) it is this script is\n$$ not paging-in each page before trying to dump a PE file. Usually pages will be there, but it could fail\n$$ to dump the entire file if a page is not mapped.\n$$ \n$$ Anyway, for debugging, i recommend to disable swapping, for having pages always in memory.\n$$\n\n$$.sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n$$.reload\n\n.logopen ${$arg1}\\dump_injected_pe_rwemem_fast.start\n.printf \"start\"\n.logclose\n\naS stage @$t19\naS temp @$t18\naS temp2 @$t17\naS temp3 @$t16\naS isPossiblePE @$t15\naS isDosMessageBased @$t14\naS pe @$t13\naS fileheader @$t12\naS optionalheader @$t11\naS sections @$t10\naS nsections @$t9\naS lastsect @$t8\naS prev1 @$t7\naS prev2 @$t6\naS baseaddr @$t5\naS baseaddrlen @$t4\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    r stage = 2\n    \n    .printf \"xxxx\"\n    \n    .foreach (processes_tok { !process 0 0 })\n    {\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Analyzing process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n        \n            .process /p /r ${processes_tok}\n            \n            $$search for memory blocks with ReadWriteExecute protection\n            \n            $$careful:\n            $$ when the baseaddress is over 0x10000000 findstr tokens will be:\n            $$ 93:7640:20010000\n            $$ 2002c000\n            $$ 1c000\n            $$ UserRange\n            $$ ...\n            $$ however if the addess is under 0x10000000:\n            $$ 25:1364:\n            $$ 60000\n            $$ 61000\n            $$ 1000\n            $$ UserRange\n            $$ The reason for this its windbg puts spaces before the base address when it hasnt 8 characters to complete 8 characters, but if the address is\n            $$ ???????? then it doesnt put spaces. We need to have in mind both case, and this is the reason of the stages of the next code\n            $$\n            \n            .foreach (tok { .shell -ci \"!address\" findstr /N /O /R /C:\"UserRange.*ExecuteReadWrite\" /C:\"UserRange.*ReadWriteExecute\" }) \n            {\n                r isPossiblePE = 0\n                r isDosMessageBased = 0\n                \n                .printf \"${tok}\\n\"\n                \n                .if($spat(\"${tok}\",\"*:*:*\")!=0)\n                {\n                    r stage = 1\n                }\n                .elsif(${stage}==1)\n                {\n                    r prev1 = ${tok}                \n                    r stage = 2\n                }\n                .elsif(${stage}==2)\n                {\n                    r prev2 = ${tok}                \n                    r stage = 3\n                }\n                .elsif(${stage}==3)\n                {\n                    .if($spat(\"${tok}\",\"*UserRange*\")!=0)\n                    {\n                        r baseaddr = prev1 - prev2\n                        r baseaddrlen = prev2\n                        r stage = 5\n                    }\n                    .else\n                    {\n                        r baseaddr = prev1\n                        r baseaddrlen = ${tok}\n                        r stage = 4\n                    }\n                }\n                .elsif(${stage}==4)\n                {\n                    r stage = 5\n                }\n                .elsif(${stage}==5)\n                {\n                    $$for each block with ReadWriteExecute protection, check MZ / PE\n                    \n                    r @$t0 = baseaddr\n                    \n                    .if(@$t0!=0)\n                    {\n                        .printf \"base %x\\n\", @$t0\n                        \n                        $$.pagein /p ${processes_tok} @$t0\n                        $$g\n                        \n                        $$!address @$t0\n                                \n                        .if($vvalid(@$t0, 2)==1)\n                        {\n                            .printf \"valid base address\\n\"\n                            \n                            .printf \"PE_header %x\\n\", @$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew)\n                                        \n                            .if($vvalid(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew), 2)==1)\n                            {\n                                .printf \"valid PE_header address\\n\"\n                                \n                                .if(wo(@$t0)==0x5a4d & dwo(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew))==0x454E)\n                                {\n                                    $$We can find MZ / NE  images, we ignore them\n                                }\n                                .elsif(wo(@$t0)==0x5a4d & dwo(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew))==0x4550)\n                                {\n                                    $$if MZ and PE signatures, valid pe header\n                                    .printf \"valid PE_header\\n\"\n                                    r isPossiblePE = 1\n                                }\n                                .else\n                                {\n                                    $$if not MZ or not PE signature, but msdos message is found, its a possible pe header\n                                    r temp = 0\n                                    .foreach (tok2 { s -a @$t0 L 0x80 \"This program cannot \" })\n                                    {\n                                        r temp = 1\n                                    }\n                                    .if(${temp}==1)\n                                    {\n                                        .printf \"possible pe header\\n\"\n                                        r isPossiblePE = 1\n                                        r isDosMessageBased = 1\n                                    }\n                                }\n                            }\n                            .else\n                            {\n                                .printf \"not valid PE_header address\\n\"\n                            }\n                        }\n                        .else\n                        {\n                            .printf \"not valid base address\\n\"\n                        }\n                        \n                        $$if we have found a possible PE in a memory zone with ReadWriteExecute protection, we will check if the base address is in the list of loaded module\n                        .if(${isPossiblePE}==1)\n                        {\n                            .printf \"is possible module %x\\n\", @$t0\n\n                            $$  r temp = 0\n                            $$  $$search for valid from \"is not valid address\"\n                            $$  .foreach (tok3 { .shell -ci \"!lmi @$t0\" findstr /N /O \"valid.address\" })\n                            $$  {\n                            $$      r temp = ${temp} + 1\n                            $$  }\n                            $$  .printf \"%x\\n\", ${temp}\n                            $$  \n                            $$  We are going to disable !lmi check. I have found malware that is unmapping\n                            $$  the main module of a executable when it does process hollowing, and it loads\n                            $$  its injected PE in that address. In this cases, !lmi is not answering not valid\n                            $$  address for that address. However !address command is containing the path\n                            $$  of the module (for example Section [\\Windows\\explorer.exe]) when the module is\n                            $$  a valid loaded module, and it wont contain the path when it is an injected module\n                            $$  in RWE mem. So, we will skip !lmi check, and we will check !address results\n                            $$ vvvvvvvv DISABLE !LMI CHECK vvvvvvvvv\n                            r temp = 4\n                            $$ ^^^^^^^^ DISABLE !LMI CHECK ^^^^^^^^^\n                            \n                            $$ \"is not valid address\" was found\n                            .if(${temp} > 3) \n                            {\n                                $$ there are some modules that !lmi command is answering: is not valid address, however they seems to be valid loaded modules (not interesing for us). \n                                $$ However if we consults information about the address with !address we find things as:  \n                                $$ Memory Usage:           Section [\\WINDOWS\\System32\\blablabla.mui] (it happens usually with .mui files, but not only with them\n                                $$ We will discard results of !address with .dll], .mui] and .exe]                        \n    \n                                r temp = 0                            \n                                .foreach (tok4 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.mui\\]\" })\n                                {\n                                    r temp = ${temp} + 1\n                                }\n    \n                                r temp2 = 0\n                                .foreach (tok5 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.dll\\]\" })\n                                {\n                                    r temp2 = ${temp2} + 1\n                                }\n    \n                                r temp3 = 0\n                                .foreach (tok6 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.exe\\]\" })\n                                {\n                                    r temp3 = ${temp3} + 1\n                                }\n    \n                                .printf \"search !address .mui %x\\n\", ${temp}\n                                .printf \"search !address .dll %x\\n\", ${temp2}\n                                .printf \"search !address .exe %x\\n\", ${temp3}\n    \n                                .if(${temp} < 4 and ${temp2} < 4 and ${temp3} < 4)\n                                {\n                                    .if(${isDosMessageBased}==0)\n                                    {\n                                        .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                        .printf /D \"<b>Process: ${processes_tok} base: %x -> Possible injected or unpacked PE</b>\\n\", @$t0\n                                        .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                    }\n                                    .else\n                                    {\n                                        .printf /D \"-------------------------------------------------------------------------------------------------------------------------------------\\n\"\n                                        .printf /D \"Process: ${processes_tok} base: %x -> Possible injected or unpacked PE, based on the dos header message: This program cannot...\\n\", @$t0\n                                        .printf /D \"--------------------------------------------------------------------------------------------------------------------------------------\\n\"                                    \n                                    }\n                                    \n                                    .printf \"xxxx1\\n\"\n                                                                        \n                                    r pe = @$t0 + poi(@$t0 + @@(#FIELD_OFFSET(nt!_IMAGE_DOS_HEADER, e_lfanew)))\n                                    \n                                    .printf \"xxxx2 %x\\n\", ${pe}\n                                    \n                                    r fileheader = ${pe} + @@(#FIELD_OFFSET(nt!_IMAGE_NT_HEADERS, FileHeader))\n                                    \n                                    .printf \"xxxx3 %x\\n\", ${fileheader}\n                                    \n                                    r optionalheader = ${pe} + @@(#FIELD_OFFSET(nt!_IMAGE_NT_HEADERS, OptionalHeader))\n                                    \n                                    .printf \"xxxx4 %x\\n\", ${optionalheader}\n                                    \n                                    r nsections = poi(${fileheader} + @@(#FIELD_OFFSET(nt!_IMAGE_FILE_HEADER, NumberOfSections )))&0xffff\n                                    \n                                    .printf \"xxxx5 %x\\n\", ${nsections}\n                                    \n                                    r sections = ${pe} + @@c++(sizeof(nt!_IMAGE_NT_HEADERS))\n                                    \n                                    .printf \"xxxx6 %x\\n\", ${sections}\n                                    \n                                    $$ reach the end of the PE file (last section rva + last section vsize)                            \n                                    r lastsect = ${sections} + ( ${nsections} - 1 ) * @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n                                    r @$t1 = @$t0 + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) ${lastsect} )->VirtualAddress ) + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) ${lastsect} )->Misc.VirtualSize )\n                                    r @$t2 = @$t0 + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) ${lastsect} )->VirtualAddress ) + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) ${lastsect} )->SizeOfRawData )\n                                    r @$t3 = @$t0\n                                    .if (@$t2 > @$t1) { r @$t1 = @$t2 } \n                                    \n                                    $$limit to dump = 0x100000 bytes\n                                    .if (@$t1-@$t0 > 0x100000) \n                                    {\n                                        r @$t1 = @$t0+0x100000\n                                    }\n                                    \n                                    .printf \"xxxx7\"\n                                    \n                                    $$ before dumping the PE, we are going to modify sections' raw offset = virtual address for coherency in the dumped PE when we analyze it with IDA or any other tool                                    \n                                    r $t2 = ${sections}\n                                    r lastsect = ${sections} + ( ${nsections} ) * @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n                                    \n                                    .while (@$t2 < ${lastsect})\n                                    {\n                                        ed (@$t2+@@( #FIELD_OFFSET(nt!_IMAGE_SECTION_HEADER, PointerToRawData))) @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->VirtualAddress)\n                                        .if( @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->SizeOfRawData) < @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->Misc.VirtualSize))\n                                        {\n                                            ed (@$t2+@@( #FIELD_OFFSET(nt!_IMAGE_SECTION_HEADER, SizeOfRawData))) @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->Misc.VirtualSize)\n                                        }\n                                        .else\n                                        {\n                                            ed (@$t2+@@( #FIELD_OFFSET(nt!_IMAGE_SECTION_HEADER, Misc))) @@c++((( nt!_IMAGE_SECTION_HEADER *)@$t2)->SizeOfRawData)\n                                        }\n                                        r $t2 = @$t2 + @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n                                    }\n                                    \n                                    $$update sizeofimage                                    \n                                    .block\n                                    {\n                                        ed (${optionalheader} + @@(#FIELD_OFFSET(nt!_IMAGE_OPTIONAL_HEADER, SizeOfImage))) (@$t1-@$t0)&0x7fffffff\n                                    }\n                                    \n                                    .printf \"xxxx8\"\n                                    \n                                    $$update imagebase\n                                    .block\n                                    {\n                                        ed (${optionalheader} + @@(#FIELD_OFFSET(nt!_IMAGE_OPTIONAL_HEADER, ImageBase))) ${baseaddr}\n                                    }\n                                    \n                                    .printf \"xxxx9\"\n                                    \n                                    .printf \"dumping file address start %x end %x\", @$t0, @$t1\n                                    \n                                    .foreach /pS 4 (baseaddr_tok { ? baseaddr })\n                                    {\n                                        .foreach /pS 4 (baseaddrlen_tok { ? baseaddrlen })\n                                        {\n                                            .printf \"${processes_tok}_${baseaddr_tok}_${baseaddrlen_tok}.pedmp\"\n                                            .writemem ${$arg1}\\${processes_tok}_${baseaddr_tok}_${baseaddrlen_tok}.pedmp @$t3 L (@$t1 - @$t3)\n                                        }\n                                    }\n                                }\n                            }           \n                        }\n                        \n                        r stage = 0\n                    }\n                }\n            }\n        \n            r stage = 0\n        }\n    }\n \n    .logopen ${$arg1}\\dump_injected_pe_rwemem_fast.end\n    .printf \"end\"\n    .logclose\n    \n    ad stage\n    ad temp\n    ad temp2\n    ad temp3\n    ad isPossiblePE\n    ad isDosMessageBased\n    ad pe\n    ad fileheader\n    ad optionalheader\n    ad sections\n    ad nsections\n    ad lastsect\n    ad prev1\n    ad prev2\n    ad baseaddr\n    ad baseaddrlen\n}"
  },
  {
    "path": "WinDbg/dump_main_module.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$ $$>a<c:\\tools\\@scripts\\windbg\\dump_main_module.wdbg <targetdir> <modname with ext> <modname without ext>\n\n.logopen ${$arg1}\\dump_main_module.start\n.printf \"start\"\n.logclose\n\n\naS stage @$t19\naS base @$t18\naS end @$t17\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload /f\n}\n\n.block\n{\n    r stage = 2\n    \n    .printf \"xxxx\"\n    \n    .foreach (processes_tok { !process /m ${$arg2} 0 0 })\n    {\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Dumping main module for process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n            \n            .process /i ${processes_tok}\n            g\n            \n            .reload /f\n            \n            .foreach (lmi_tok { lmi m ${$arg3} })\n            {\n                r stage = stage + 1\n                \n                .if(${stage}==5)\n                {\n                    .printf \"${lmi_tok}\\r\\n\"\n                    r base = ${lmi_tok}\n                }\n                .if(${stage}==6)\n                {\n                    .printf \"${lmi_tok}\\r\\n\"\n                    r end = ${lmi_tok}\n                }\n            }\n            \n            .if (${end} - ${base} > 0x100000) { r end = ${base} + 0x100000 }\n            \n            .foreach /pS 4 (baseaddr_tok { ? ${base} })\n            {\n                .foreach /pS 4 (endaddr_tok { ? ${end} })\n                {\n                    .printf \"[${processes_tok}] ${baseaddr_tok} - ${endaddr_tok}\\r\\n\"\n                    \n                    .block\n                    {\n                        $$>a<c:\\tools\\@scripts\\windbg\\secure_writemem.wdbg ${baseaddr_tok} ${endaddr_tok} ${processes_tok} ${$arg1} mainmod.pedmp\n                    }\n                }\n            }\n            \n            r stage = 0\n        }\n    }\n}\n\n.logopen ${$arg1}\\dump_main_module.end\n.printf \"end\"\n.logclose\n"
  },
  {
    "path": "WinDbg/dump_pe.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<c:\\tools\\@scripts\\windbg\\dump_pe.wdbg <base_address> <process> <path>\n\n$$     it uses t0, t1 and t2\n\n$$.sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n$$.reload\n\n.printf \"dump pe base address %x, process %x\\n\", ${$arg1}, ${$arg2}\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n$$ change the context to the target process and page in the page containing PE headers\n.process /i ${$arg2}\ng\n$$.reload /user\n.pagein /p ${$arg2} ${$arg1}\ng\n\n.block\n{\n\n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$ define some useful aliases\n    \n    ad /q ${/v:$imagebase};\n    ad /q ${/v:$pe_header};\n    ad /q ${/v:$file_header};\n    ad /q ${/v:$optional_header};\n    ad /q ${/v:$number_of_sections};\n    ad /q ${/v:$sections};\n    \n    aS /x ${/v:$imagebase} ( ${$arg1} )\n    aS /x ${/v:$pe_header} ( $imagebase + ( poi( $imagebase + @@( #FIELD_OFFSET( nt!_IMAGE_DOS_HEADER, e_lfanew ) ) ) ) )\n    aS /x ${/v:$file_header} ( $pe_header + @@( #FIELD_OFFSET( nt!_IMAGE_NT_HEADERS, FileHeader ) ) )\n    aS /x ${/v:$optional_header} ( $pe_header + @@( #FIELD_OFFSET( nt!_IMAGE_NT_HEADERS, OptionalHeader ) ) )\n    aS /x ${/v:$number_of_sections} ( poi ( $file_header + @@( #FIELD_OFFSET( nt!_IMAGE_FILE_HEADER, NumberOfSections ) ) ) & 0xffff )\n    aS /x ${/v:$sections} ( $pe_header + @@c++( sizeof ( nt!_IMAGE_NT_HEADERS ) ) )\n    \n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$ we are going to set sections' raw offset = virtual address for coherency in the dumped PE\n    \n    r $t0 = $sections\n    r $t1 = 0\n    r $t2 = $number_of_sections\n    \n    .while (@$t1 < @$t2)\n    {\n        r $t3 = $sections + @$t1 * @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n        $$.printf \"%x\\n\", @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) @$t3 )->VirtualAddress )\n        $$.printf \"%x\\n\", @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) @$t3 )->PointerToRawData )\n        r $t4 = @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) @$t3 )->VirtualAddress )\n        r $t5 = @$t3 + @@( #FIELD_OFFSET( nt!_IMAGE_SECTION_HEADER, PointerToRawData ) )\n        ed $t5 $t4\n        r $t1 = @$t1 + 1\n    }\n    \n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$ now we are going to page in all the pages of the PE file in memory\n    \n    r $t0 = $sections + ( $number_of_sections - 1 ) * @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n    r $t1 = $imagebase + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) @$t0 )->VirtualAddress ) + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) @$t0 )->Misc.VirtualSize )\n    r $t2 = $imagebase + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) @$t0 )->VirtualAddress ) + @@c++( ( ( nt!_IMAGE_SECTION_HEADER * ) @$t0 )->SizeOfRawData )\n    \n    .if ($t2 > $t1) { r $t1 = $t2 } \n    \n    r $t0 = $imagebase\n    \n    ? $t0\n    ? $t1\n    \n    .while (@$t0 < @$t1)\n    {\n        .printf \"paging in: %x\\n\", @$t0\n        .pagein /p ${$arg2} @$t0\n        g\n        r $t0 = @$t0 + 0x1000;\n    };\n    \n    ? $t1 - $imagebase\n    \n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$ finally we are going to write the entire PE file to disk\n    \n    .writemem ${$arg3} $imagebase L $t1 - $imagebase\n\n}    "
  },
  {
    "path": "WinDbg/dump_process_symbols_to_file.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$\n$$ $$>a<dump_process_symbols_to_file.wdbg <path> <proc>\n$$\n$$ This simple script will dump to a file all the symbols of the given process.\n$$ If you dump a PE from memory, it could have variables pointing to symbols (for example, api addresses that it got with GetProcAddress, etc...).\n$$ It is useful to have a list of pairs (symbol, address) because in this way if we open the dumped PE with IDA we can search for that addresses\n$$ and set a name for the variable containing them.\n$$\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    .process /i ${$arg2}\n    g\n    \n    .block\n    {\n        .reload\n    }\n    \n    .block\n    {\n        .reload /user\n    }\n       \n    .block { .shell -i- -ci \"x *!*\" findstr \"!\">${$arg1} }\n}"
  },
  {
    "path": "WinDbg/dump_process_symbols_to_file_preselect.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$\n$$ $$>a<dump_process_symbols_to_file_preselect.wdbg <path> <proc>\n$$\n$$ This simple script will dump to a file symbols of a preselection of common dlls of the given process.\n$$ If you dump a PE from memory, it could have variables pointing to symbols (for example, api addresses that it got with GetProcAddress, etc...).\n$$ It is useful to have a list of pairs (symbol, address) because in this way if we open the dumped PE with IDA we can search for that addresses\n$$ and set a name for the variable containing them.\n$$\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    .process /i ${$arg2}\n    g\n    \n    .block\n    {\n        .reload\n    }\n    \n    .block\n    {\n        .reload /user\n    }\n       \n    r $t0 = 0; .foreach ( tok { lm m kernel32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"kernel32\";\n        .block { .shell -i- -ci \"x kernel32!*\" findstr \"!\">${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m user32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"user32\";\n        .block { .shell -i- -ci \"x user32!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m advapi32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"advapi32\";\n        .block { .shell -i- -ci \"x advapi32!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m ws2_32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"ws2_32\";\n        .block { .shell -i- -ci \"x ws2_32!*\" findstr \"!\">>${$arg1} };\n    }\n\n    r $t0 = 0; .foreach ( tok { lm m wininet } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"wininet\";\n        .block { .shell -i- -ci \"x wininet!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m ntdll } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"ntdll\";\n        .block { .shell -i- -ci \"x ntdll!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m crypt32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"crypt32\";\n        .block { .shell -i- -ci \"x crypt32!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m dnsapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"dnsapi\";\n        .block { .shell -i- -ci \"x dnsapi!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m shlwapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"shlwapi\";\n        .block { .shell -i- -ci \"x shlwapi!*\" findstr \"!\">>${$arg1} };    \n    }\n\n    r $t0 = 0; .foreach ( tok { lm m winhttp } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"winhttp\";\n        .block { .shell -i- -ci \"x winhttp!*\" findstr \"!\">>${$arg1} };   \n    }\n        \n    r $t0 = 0; .foreach ( tok { lm m sysdm } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"sysdm\";\n        .block { .shell -i- -ci \"x sysdm!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m rpcrt4 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"rpcrt4\";\n        .block { .shell -i- -ci \"x rpcrt4!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m iphlpapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"iphlpapi\";\n        .block { .shell -i- -ci \"x iphlpapi!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m powrprof } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"powrprof\";\n        .block { .shell -i- -ci \"x powrprof!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m gdi32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"gdi32\";\n        .block { .shell -i- -ci \"x gdi32!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m msvcrt } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"msvcrt\";\n        .block { .shell -i- -ci \"x msvcrt*!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m msvcp } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"msvcp\";\n        .block { .shell -i- -ci \"x msvcp*!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m winmm } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"winmn\";\n        .block { .shell -i- -ci \"x winmm!*\" findstr \"!\">>${$arg1} };\n    }\n\n    r $t0 = 0; .foreach ( tok { lm m gdiplus } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"gdiplus\";\n        .block { .shell -i- -ci \"x gdiplus!*\" findstr \"!\">>${$arg1} };\n    }\n\n    r $t0 = 0; .foreach ( tok { lm m psapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"psapi\";\n        .block { .shell -i- -ci \"x psapi!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m urlmon } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"urlmon\";\n        .block { .shell -i- -ci \"x urlmon!*\" findstr \"!\">>${$arg1} };\n    }\n\n    r $t0 = 0; .foreach ( tok { lm m netapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"netapi\";\n        .block { .shell -i- -ci \"x netapi!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m ole32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"netapi\";\n        .block { .shell -i- -ci \"x ole32!*\" findstr \"!\">>${$arg1} };\n    }    \n    \n}"
  },
  {
    "path": "WinDbg/dump_process_symbols_to_file_preselect_curproc.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$\n$$ $$>a<dump_process_symbols_to_file_preselect.wdbg <path>\n$$\n$$ This simple script will dump to a file symbols of a preselection of common dlls of the given process.\n$$ If you dump a PE from memory, it could have variables pointing to symbols (for example, api addresses that it got with GetProcAddress, etc...).\n$$ It is useful to have a list of pairs (symbol, address) because in this way if we open the dumped PE with IDA we can search for that addresses\n$$ and set a name for the variable containing them.\n$$\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    .block\n    {\n        .reload\n    }\n    \n    .block\n    {\n        .reload /user\n    }\n       \n    r $t0 = 0; .foreach ( tok { lm m kernel32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"kernel32\";\n        .block { .shell -i- -ci \"x kernel32!*\" findstr \"!\">${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m user32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"user32\";\n        .block { .shell -i- -ci \"x user32!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m advapi32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"advapi32\";\n        .block { .shell -i- -ci \"x advapi32!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m ws2_32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"ws2_32\";\n        .block { .shell -i- -ci \"x ws2_32!*\" findstr \"!\">>${$arg1} };\n    }\n\n    r $t0 = 0; .foreach ( tok { lm m wininet } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"wininet\";\n        .block { .shell -i- -ci \"x wininet!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m ntdll } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"ntdll\";\n        .block { .shell -i- -ci \"x ntdll!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m crypt32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"crypt32\";\n        .block { .shell -i- -ci \"x crypt32!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m dnsapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"dnsapi\";\n        .block { .shell -i- -ci \"x dnsapi!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m shlwapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"shlwapi\";\n        .block { .shell -i- -ci \"x shlwapi!*\" findstr \"!\">>${$arg1} };    \n    }\n\n    r $t0 = 0; .foreach ( tok { lm m winhttp } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"winhttp\";\n        .block { .shell -i- -ci \"x winhttp!*\" findstr \"!\">>${$arg1} };   \n    }\n        \n    r $t0 = 0; .foreach ( tok { lm m sysdm } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"sysdm\";\n        .block { .shell -i- -ci \"x sysdm!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m rpcrt4 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"rpcrt4\";\n        .block { .shell -i- -ci \"x rpcrt4!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m iphlpapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"iphlpapi\";\n        .block { .shell -i- -ci \"x iphlpapi!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m powrprof } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"powrprof\";\n        .block { .shell -i- -ci \"x powrprof!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m gdi32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"gdi32\";\n        .block { .shell -i- -ci \"x gdi32!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m msvcrt } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"msvcrt\";\n        .block { .shell -i- -ci \"x msvcrt*!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m msvcp } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"msvcp\";\n        .block { .shell -i- -ci \"x msvcp*!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m winmm } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    { \n        .printf \"winmn\";\n        .block { .shell -i- -ci \"x winmm!*\" findstr \"!\">>${$arg1} };\n    }\n\n    r $t0 = 0; .foreach ( tok { lm m gdiplus } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"gdiplus\";\n        .block { .shell -i- -ci \"x gdiplus!*\" findstr \"!\">>${$arg1} };\n    }\n\n    r $t0 = 0; .foreach ( tok { lm m psapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"psapi\";\n        .block { .shell -i- -ci \"x psapi!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m urlmon } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"urlmon\";\n        .block { .shell -i- -ci \"x urlmon!*\" findstr \"!\">>${$arg1} };\n    }\n\n    r $t0 = 0; .foreach ( tok { lm m netapi } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"netapi\";\n        .block { .shell -i- -ci \"x netapi!*\" findstr \"!\">>${$arg1} };\n    }\n    \n    r $t0 = 0; .foreach ( tok { lm m ole32 } ){ r $t0 = @$t0 + 1; }; \n    .if( $t0 > 8 )\n    {     \n        .printf \"netapi\";\n        .block { .shell -i- -ci \"x ole32!*\" findstr \"!\">>${$arg1} };\n    }    \n    \n}"
  },
  {
    "path": "WinDbg/find_injected_pe_rmem.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<c:\\tools\\@scripts\\windbg\\find_injected_pe_rmem.wdbg\n\n$$.sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n$$.reload\n\naS stage @$t19\naS temp @$t18\naS temp2 @$t17\naS temp3 @$t16\naS isPossiblePE @$t15\naS isDosMessageBased @$t14\naS prev1 @$t7\naS prev2 @$t6\naS baseaddr @$t5\naS baseaddrlen @$t4\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    r stage = 2\n    \n    .printf \"xxxx\"\n    \n    .foreach (processes_tok { !process 0 0 })\n    {\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Analyzing process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n        \n            .process /i ${processes_tok}\n            g\n            \n            .block\n            {\n                .reload /user\n            }\n            \n            $$search for memory blocks\n            \n            $$careful:\n            $$ when the baseaddress is over 0x10000000 findstr tokens will be:\n            $$ 93:7640:20010000\n            $$ 2002c000\n            $$ 1c000\n            $$ UserRange\n            $$ ...\n            $$ however if the addess is under 0x10000000:\n            $$ 25:1364:\n            $$ 60000\n            $$ 61000\n            $$ 1000\n            $$ UserRange\n            $$ The reason for this its windbg puts spaces before the base address when it hasnt 8 characters to complete 8 characters, but if the address is\n            $$ ???????? then it doesnt put spaces. We need to have in mind both case, and this is the reason of the stages of the next code\n            $$\n            \n            .foreach (tok { .shell -ci \"!address\" findstr /N /O \"UserRange.*Read\" }) \n            {\n                r isPossiblePE = 0\n                r isDosMessageBased = 0\n                \n                .printf \"${tok}\\n\"\n                \n                .if($spat(\"${tok}\",\"*:*:*\")!=0)\n                {\n                    r stage = 1\n                }\n                .elsif(${stage}==1)\n                {\n                    r prev1 = ${tok}                \n                    r stage = 2\n                }\n                .elsif(${stage}==2)\n                {\n                    r prev2 = ${tok}                \n                    r stage = 3\n                }\n                .elsif(${stage}==3)\n                {\n                    .if($spat(\"${tok}\",\"*UserRange*\")!=0)\n                    {\n                        r baseaddr = prev1 - prev2\n                        r baseaddrlen = prev2\n                        r stage = 5\n                    }\n                    .else\n                    {\n                        r baseaddr = prev1\n                        r baseaddrlen = ${tok}\n                        r stage = 4\n                    }\n                }\n                .elsif(${stage}==4)\n                {\n                    r stage = 5\n                }\n                .elsif(${stage}==5)\n                {\n                    $$for each block, check MZ / PE\n                    \n                    r @$t0 = baseaddr\n                    \n                    .if(@$t0!=0)\n                    {\n                        .printf \"base %x\\n\", @$t0\n                        \n                        .pagein /p ${processes_tok} @$t0\n                        g\n                        \n                        $$!address @$t0\n                                \n                        .if($vvalid(@$t0, 2)==1)\n                        {\n                            .printf \"valid base address\\n\"\n                            \n                            .printf \"pe %x\\n\", @$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew)\n                                        \n                            .if($vvalid(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew), 2)==1)\n                            {\n                                .printf \"valid pe header address\\n\"\n                                \n                                .if(wo(@$t0)==0x5a4d & dwo(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew))==0x454E)\n                                {\n                                    $$We can find MZ / NE  images, we ignore them\n                                }\n                                .elsif(wo(@$t0)==0x5a4d & dwo(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew))==0x4550)\n                                {\n                                    $$if MZ and PE signatures, valid pe header\n                                    .printf \"valid pe header\\n\"\n                                    r isPossiblePE = 1\n                                }\n                                .else\n                                {\n                                    $$if not MZ or not PE signature, but msdos message is found, its a possible pe header\n                                    r temp = 0\n                                    .foreach (tok2 { s -a @$t0 L 0x80 \"This program cannot \" })\n                                    {\n                                        r temp = 1\n                                    }\n                                    .if(${temp}==1)\n                                    {\n                                        .printf \"possible pe header\\n\"\n                                        r isPossiblePE = 1\n                                        r isDosMessageBased = 1\n                                    }\n                                }\n                            }\n                        }\n                        \n                        $$if we have found a possible PE in a memory zone with ReadWriteExecute protection, we will check if the base address is in the list of loaded module\n                        .if(${isPossiblePE}==1)\n                        {\n                            .printf \"is possible module %x\\n\", @$t0\n                            r temp = 0\n                            $$search for valid from \"is not valid address\"\n                            .foreach (tok3 { .shell -ci \"!lmi @$t0\" findstr /N /O \"valid.address\" })\n                            {\n                                r temp = ${temp} + 1\n                            }\n                            .printf \"%x\\n\", ${temp}\n                            $$ \"is not valid address\" was found\n                            .if(${temp} > 3) \n                            {\n                                $$ there are some modules that !lmi command is answering: is not valid address, however they seems to be valid loaded modules (not interesing for us). \n                                $$ However if we consults information about the address with !address we find things as:  \n                                $$ Memory Usage:           Section [\\WINDOWS\\System32\\blablabla.mui] (it happens usually with .mui files, but not only with them\n                                $$ We will discard results of !address with .dll], .mui] and .exe]                        \n    \n                                r temp = 0                            \n                                .foreach (tok4 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.mui\\]\" })\n                                {\n                                    r temp = ${temp} + 1\n                                }\n    \n                                r temp2 = 0\n                                .foreach (tok5 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.dll\\]\" })\n                                {\n                                    r temp2 = ${temp2} + 1\n                                }\n    \n                                r temp3 = 0\n                                .foreach (tok6 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.exe\\]\" })\n                                {\n                                    r temp3 = ${temp3} + 1\n                                }\n    \n                                .printf \"search !address .mui %x\\n\", ${temp}\n                                .printf \"search !address .dll %x\\n\", ${temp2}\n                                .printf \"search !address .exe %x\\n\", ${temp3}\n    \n                                .if(${temp} < 4 and ${temp2} < 4 and ${temp3} < 4)\n                                {\n                                    .if(${isDosMessageBased}==0)\n                                    {\n                                        .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                        .printf /D \"<b>Process: ${processes_tok} base: %x -> Possible injected or unpacked PE</b>\\n\", @$t0\n                                        .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                    }\n                                    .else\n                                    {\n                                        .printf /D \"-------------------------------------------------------------------------------------------------------------------------------------\\n\"\n                                        .printf /D \"Process: ${processes_tok} base: %x -> Possible injected or unpacked PE, based on the dos header message: This program cannot...\\n\", @$t0\n                                        .printf /D \"--------------------------------------------------------------------------------------------------------------------------------------\\n\"                                    \n                                    }\n                                }\n                            }           \n                        }\n                        \n                        r stage = 0\n                    }\n                }\n            }\n        \n            r stage = 0\n        }\n    }\n    \n    ad stage\n    ad temp\n    ad temp2\n    ad temp3\n    ad isPossiblePE\n    ad isDosMessageBased\n    ad prev1\n    ad prev2\n    ad baseaddr\n    ad baseaddrlen\n}"
  },
  {
    "path": "WinDbg/find_injected_pe_rwemem.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$ $$>a<find_injected_pe_rwemem.wdbg\n$$\n$$ This windbg script will walk the results of !address command for each process in the debuggee machine, \n$$ searching for RWE memory containing PE files (based on the analysis of PE header). \n$$ \n\n$$.sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n$$.reload\n\naS stage @$t19\naS temp @$t18\naS temp2 @$t17\naS temp3 @$t16\naS isPossiblePE @$t15\naS isDosMessageBased @$t14\naS prev1 @$t7\naS prev2 @$t6\naS baseaddr @$t5\naS baseaddrlen @$t4\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    r stage = 2\n    \n    .printf \"xxxx\"\n    \n    .foreach (processes_tok { !process 0 0 })\n    {\n        .printf \"${processes_tok}\\n\"\n\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Analyzing process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n        \n            .process /i ${processes_tok}\n            g\n            \n            .block\n            {\n                .reload /user\n            }\n            \n            $$search for memory blocks with ReadWriteExecute protection\n            \n            $$careful:\n            $$ when the baseaddress is over 0x10000000 findstr tokens will be:\n            $$ 93:7640:20010000\n            $$ 2002c000\n            $$ 1c000\n            $$ UserRange\n            $$ ...\n            $$ however if the addess is under 0x10000000:\n            $$ 25:1364:\n            $$ 60000\n            $$ 61000\n            $$ 1000\n            $$ UserRange\n            $$ The reason for this its windbg puts spaces before the base address when it hasnt 8 characters to complete 8 characters, but if the address is\n            $$ ???????? then it doesnt put spaces. We need to have in mind both case, and this is the reason of the stages of the next code\n            $$\n            \n            .foreach (tok { .shell -ci \"!address\" findstr /N /O /R /C:\"UserRange.*ExecuteReadWrite\" /C:\"UserRange.*ReadWriteExecute\" }) \n            {\n                r isPossiblePE = 0\n                r isDosMessageBased = 0\n                \n                .printf \"${tok}\\n\"\n                \n                .if($spat(\"${tok}\",\"*:*:*\")!=0)\n                {\n                    r stage = 1\n                }\n                .elsif(${stage}==1)\n                {\n                    r prev1 = ${tok}                \n                    r stage = 2\n                }\n                .elsif(${stage}==2)\n                {\n                    r prev2 = ${tok}                \n                    r stage = 3\n                }\n                .elsif(${stage}==3)\n                {\n                    .if($spat(\"${tok}\",\"*UserRange*\")!=0)\n                    {\n                        r baseaddr = prev1 - prev2\n                        r baseaddrlen = prev2\n                        r stage = 5\n                    }\n                    .else\n                    {\n                        r baseaddr = prev1\n                        r baseaddrlen = ${tok}\n                        r stage = 4\n                    }\n                }\n                .elsif(${stage}==4)\n                {\n                    r stage = 5\n                }\n                .elsif(${stage}==5)\n                {\n                    $$for each block with ReadWriteExecute protection, check MZ / PE\n                    \n                    r @$t0 = baseaddr\n                    \n                    .if(@$t0!=0)\n                    {\n                        .printf \"base %x\\n\", @$t0\n                        \n                        .pagein /p ${processes_tok} @$t0\n                        g\n                        \n                        $$!address @$t0\n                                \n                        .if($vvalid(@$t0, 2)==1)\n                        {\n                            .printf \"valid base address\\n\"\n                            \n                            .printf \"pe %x\\n\", @$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew)\n                                        \n                            .if($vvalid(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew), 2)==1)\n                            {\n                                .printf \"valid pe header address\\n\"\n                                \n                                .if(wo(@$t0)==0x5a4d & dwo(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew))==0x454E)\n                                {\n                                    $$We can find MZ / NE  images, we ignore them\n                                }\n                                .elsif(wo(@$t0)==0x5a4d & dwo(@$t0+@@c++(((nt!_IMAGE_DOS_HEADER * )@$t0)->e_lfanew))==0x4550)\n                                {\n                                    $$if MZ and PE signatures, valid pe header\n                                    .printf \"valid pe header\\n\"\n                                    r isPossiblePE = 1\n                                }\n                                .else\n                                {\n                                    $$if not MZ or not PE signature, but msdos message is found, its a possible pe header\n                                    r temp = 0\n                                    .foreach (tok2 { s -a @$t0 L 0x80 \"This program cannot \" })\n                                    {\n                                        r temp = 1\n                                    }\n                                    .if(${temp}==1)\n                                    {\n                                        .printf \"possible pe header\\n\"\n                                        r isPossiblePE = 1\n                                        r isDosMessageBased = 1\n                                    }\n                                }\n                            }\n                        }\n                        \n                        $$if we have found a possible PE in a memory zone with ReadWriteExecute protection, we will check if the base address is in the list of loaded module\n                        .if(${isPossiblePE}==1)\n                        {\n                            .printf \"is possible module %x\\n\", @$t0\n                            r temp = 0\n                            $$search for valid from \"is not valid address\"\n                            .foreach (tok3 { .shell -ci \"!lmi @$t0\" findstr /N /O \"valid.address\" })\n                            {\n                                r temp = ${temp} + 1\n                            }\n                            .printf \"%x\\n\", ${temp}\n                            $$ \"is not valid address\" was found\n                            .if(${temp} > 3) \n                            {\n                                $$ there are some modules that !lmi command is answering: is not valid address, however they seems to be valid loaded modules (not interesing for us). \n                                $$ However if we consults information about the address with !address we find things as:  \n                                $$ Memory Usage:           Section [\\WINDOWS\\System32\\blablabla.mui] (it happens usually with .mui files, but not only with them\n                                $$ We will discard results of !address with .dll], .mui] and .exe]                        \n    \n                                r temp = 0                            \n                                .foreach (tok4 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.mui\\]\" })\n                                {\n                                    r temp = ${temp} + 1\n                                }\n    \n                                r temp2 = 0\n                                .foreach (tok5 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.dll\\]\" })\n                                {\n                                    r temp2 = ${temp2} + 1\n                                }\n    \n                                r temp3 = 0\n                                .foreach (tok6 { .shell -ci \"!address @$t0\" findstr /N /O /R /I \"\\.exe\\]\" })\n                                {\n                                    r temp3 = ${temp3} + 1\n                                }\n    \n                                .printf \"search !address .mui %x\\n\", ${temp}\n                                .printf \"search !address .dll %x\\n\", ${temp2}\n                                .printf \"search !address .exe %x\\n\", ${temp3}\n    \n                                .if(${temp} < 4 and ${temp2} < 4 and ${temp3} < 4)\n                                {\n                                    .if(${isDosMessageBased}==0)\n                                    {\n                                        .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                        .printf /D \"<b>Process: ${processes_tok} base: %x -> Possible injected or unpacked PE</b>\\n\", @$t0\n                                        .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                    }\n                                    .else\n                                    {\n                                        .printf /D \"-------------------------------------------------------------------------------------------------------------------------------------\\n\"\n                                        .printf /D \"Process: ${processes_tok} base: %x -> Possible injected or unpacked PE, based on the dos header message: This program cannot...\\n\", @$t0\n                                        .printf /D \"--------------------------------------------------------------------------------------------------------------------------------------\\n\"                                    \n                                    }\n                                }\n                            }           \n                        }\n                        \n                        r stage = 0\n                    }\n                }\n            }\n        \n            r stage = 0\n        }\n    }\n    \n    ad stage\n    ad temp\n    ad temp2\n    ad temp3\n    ad isPossiblePE\n    ad isDosMessageBased\n    ad prev1\n    ad prev2\n    ad baseaddr\n    ad baseaddrlen\n}"
  },
  {
    "path": "WinDbg/find_injected_pe_search.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$ $$>a<find_injected_pe_search.wdbg\n$$\n$$ This windbg script will search for PE headers. Later, it checks !lmi results for checking of the found PE header matchs a loaded module.\n$$ If not, it reports that PE (assuming it could be an unpacked or injected PE).\n$$\n\n$$.sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n$$.reload\n\n$$.foreach ( header {s -[1]d 0x0 L?0xffffffff 0x00905a4d} ) \n$${\n$$    .echo \"****HEADER****\"\n$$    !lmi header\n$$}\n\n$$.foreach /ps 0x10 ( header {s 0 L?0x80000000 4d 5a 90 00} ) \n$${\n$$    .echo \"****HEADER****\"\n$$    !lmi header\n$$}\n\naS stage @$t19\naS temp @$t18\naS baseSearch @$t17\naS stop @$t16\naS temp2 @$t15\naS temp3 @$t14\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    r stage = 2\n    \n    .foreach (processes_tok { !process 0 0 })\n    {\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Analyzing process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n        \n            .process /i ${processes_tok}\n            g\n            \n            .block\n            {\n                .reload\n            }\n            \n            .block\n            {\n                .reload /user\n            }\n        \n            r ${stop} = 0\n            r ${baseSearch} = 0\n        \n            .while(${stop} == 0)\n            {\n                .printf \"searching base %x\\n\", ${baseSearch}\n                \n                r @$t0 = ${baseSearch}\n                \n                .foreach /ps 0x10 ( header {s @$t0 L?0x10000000 4d 5a 90 00} )\n                {\n                    r temp = 0\n                    r @$t0 = ${header}\n                    \n                    .printf \"MZ at ${header}\\n\"\n                    \n                    .if(poi(${header}+3c) < 0x2ff)\n                    {\n                        .if(poi(${header}+poi(${header}+3c)) == 0x00004550)\n                        {\n                            .printf \"PE signature found\\n\"\n                            \n                            $$search for valid from: is not valid address\n                            .foreach (tok { .shell -ci \"!lmi ${header}\" findstr /N /O /R /I \"valid.address\" }) \n                            {\n                                r temp = ${temp} + 1\n                            }\n                            .printf \"search valid address %x\\n\", ${temp}\n                            \n                            $$ \"is not valid address was found\"\n                            .if(${temp} > 3)\n                            {\n                                $$ there are some modules that !lmi command is answering: is not valid address, however they seems to be valid loaded modules (not interesing for us). \n                                $$ However if we consults information about the address with !address we find things as:  \n                                $$ Memory Usage:           Section [\\WINDOWS\\System32\\blablabla.mui] (it happens usually with .mui files, but not only with them\n                                $$ We will discard results of !address with .dll], .mui] and .exe]\n    \n                                r temp = 0                            \n                                .foreach (tok2 { .shell -ci \"!address ${header}\" findstr /N /O /R /I \"\\.mui\\]\" })\n                                {\n                                    r temp = ${temp} + 1\n                                }\n    \n                                r temp2 = 0\n                                .foreach (tok3 { .shell -ci \"!address ${header}\" findstr /N /O /R /I \"\\.dll\\]\" })\n                                {\n                                    r temp2 = ${temp2} + 1\n                                }\n    \n                                r temp3 = 0\n                                .foreach (tok4 { .shell -ci \"!address ${header}\" findstr /N /O /R /I \"\\.exe\\]\" })\n                                {\n                                    r temp3 = ${temp3} + 1\n                                }\n    \n                                .printf \"search !address .mui %x\\n\", ${temp}\n                                .printf \"search !address .dll %x\\n\", ${temp2}\n                                .printf \"search !address .exe %x\\n\", ${temp3}\n    \n                                .if(${temp} < 4 and ${temp2} < 4 and ${temp3} < 4)\n                                {\n                                    .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                    .printf /D \"<b>Process: ${processes_tok} base: %x -> Possible injected or unpacked PE</b>\\n\", @$t0\n                                    .printf /D \"<b>---------------------------------------------------------------------------</b>\\n\"\n                                }\n                            }\n                        }\n                        .else\n                        {\n                            .printf \"PE signature not found\\n\"\n                        }\n                    }\n                    .else\n                    {\n                        .printf \"Invalid lfanew\\n\"\n                    }\n                }\n    \n                .if(${baseSearch} >= 0x70000000)\n                {\n                    .printf \"next process\\n\"\n                    r ${stop} = 1\n                }\n                \n                r ${baseSearch} = ${baseSearch} + 0x10000000            \n            }\n        }    \n    }\n    \n    ad stage\n    ad temp\n    ad baseSearch\n    ad stop\n    ad temp2\n    ad temp3\n}"
  },
  {
    "path": "WinDbg/find_objects_by_name.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<c:\\tools\\@scripts\\windbg\\find_objects_by_name.wdbg <process> <type> <name matching word>\n$$\n$$     Types: Event, Section, File, Port, Directory, SymbolicLink, Mutant, WindowStation, Semaphore, Key, Token, Process, Thread, Desktop, IoCompletion, Timer, Job, and WaitablePort\n$$     \n$$     If process == 0, all processes\n$$     If type == All, search all types\n$$     If name matching word == *, any name\n\naS stage @$t19\naS lastproc @$t18\naS lastobject @$t17\naS lasttypevalid @$t16\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n\n.block\n{    \n    $$ STAGE == 1 last token was PROCESS\n    $$ STAGE == 2 last token was Directory\n    $$ STAGE == 3 last token was Object:\n    $$ STAGE == 4 last token was Name:\n    $$ STAGE == 5 last token was Type:\n    \n    r stage = 0\n    \n    .foreach (handle_tok { !handle 0 3 ${$arg1} ${$arg2} })\n    {\n        $$ .printf \"token = ${handle_tok}\\n\"\n        \n        .if($scmp(\"\\${handle_tok}\",\"\\\\\")==0)\n        {\n        }\n        .else\n        {    \n            .if(${stage}==1)\n            {\n                .if($scmp(\"${handle_tok}\",\"HANDLE\")!=0)\n                {\n                    $$ .printf \"stage1 ${handle_tok}\\n\"\n                    r ${lastproc} = ${handle_tok}\n                }\n                r stage = 0\n            }\n            .elsif(${stage}==2)\n            {\n                $$ if Directory found, skip next Object: word\n                $$ .printf \"stage2\\n\"\n                r stage = 0\n            }\n            .elsif(${stage}==3)\n            {\n                $$ .printf \"stage3 ${handle_tok}\\n\"\n                r ${lastobject} = ${handle_tok}\n                r stage = 0\n            }\n            .elsif(${stage}==4)\n            {\n                $$ .printf \"stage4\\n\"\n                .if(${lasttypevalid}==1)\n                {\n                    r @$t0 = 0\n                    \n                    .if($scmp(\"*\",\"${$arg3}\")==0)\n                    {\n                        r @$t0 = 4\n                    }\n                    .else\n                    {\n                        .foreach (toktemp { .shell -ci \"!object ${lastobject}\" findstr /N /O \"${$arg3}\" })\n                        {\n                            r @$t0 = @$t0 + 1\n                        }\n                    }\n                    \n                    .if(@$t0 > 3)\n                    {\n                        .printf \"Process %x \", ${lastproc}\n                        !object ${lastobject}\n                    }\n                }\n                r stage = 0\n            }\n            .elsif(${stage}==5)\n            {\n                r stage = 6\n            }\n            .elsif(${stage}==6)\n            {\n                $$ .printf \"stage6 ${handle_tok}\\n\"\n                r lasttypevalid = 0\n                .if($scmp(\"${handle_tok}\",\"${$arg2}\")==0)\n                {\n                    r lasttypevalid = 1\n                }\n                .if($scmp(\"All\",\"${$arg2}\")==0)\n                {\n                    r lasttypevalid = 1\n                }   \n                r stage = 0\n            }\n            .elsif($scmp(\"${handle_tok}\",\"PROCESS\")==0)\n            {\n                $$ .printf \"PROCESS\\n\"\n                r stage = 1\n            }\n        \n            .elsif($scmp(\"${handle_tok}\",\"Directory\")==0)\n            {\n                $$ .printf \"Image:\\n\"\n                r stage = 2\n            }\n            \n            .elsif($scmp(\"${handle_tok}\",\"Object:\")==0)\n            {\n                $$ .printf \"Object:\\n\"\n                r stage = 3\n            }\n            \n            .elsif($scmp(\"${handle_tok}\",\"Name:\")==0)\n            {\n                $$ .printf \"Name:\\n\"\n                r stage = 4\n            }        \n        \n            .elsif($scmp(\"${handle_tok}\",\"Type:\")==0)\n            {\n                $$ .printf \"Type:\\n\"\n                r stage = 5\n            }  \n        }     \n    }\n\n    ad stage\n    ad lastproc\n    ad lastobject\n    ad lasttypevalid\n}"
  },
  {
    "path": "WinDbg/hang_exited_processes.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<c:\\tools\\@scripts\\windbg\\hang_exited_processes.wdbg <dir start/end files>\n\n.logopen ${$arg1}\\hang_exited_processes.start\n.printf \"start\"\n.logclose\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\nr @$t0 = nt!KeDelayExecutionThread\nr @$t1 = nt!NtTerminateProcess\n\n$$push [interval]\neb @$t1 0x68  \ned @$t1+1 @$t1+0x24\n\n$$push FALSE <no alertable>\neb @$t1+5 0x68 \ned @$t1+6 0x0\n\n$$push UserMode\neb @$t1+0xa 0x68 \ned @$t1+0xb 0x1\n\n$$push 0 <fake ret addr>\neb @$t1+0xf 0x68 \ned @$t1+0x10 0x0\n\n$$push nt!KeDelayExecutionThread / ret\neb @$t1+0x14 0x68\ned @$t1+0x15 @$t0\neb @$t1+0x19 0xc3\n\n$$interval\ned @$t1+0x24 0x00000000  \ned @$t1+0x28 0xf0000000\n\n.logopen ${$arg1}\\hang_exited_processes.end\n.printf \"end\"\n.logclose"
  },
  {
    "path": "WinDbg/isx64.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\naS x64arch $t0\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    $$is x64?\n    r x64arch = 0; \n    .foreach( tok { .effmach } ) \n    {\n        .if($scmp(\"${tok}\",\"x64\")==0)\n        {\n            r x64arch = 1;\n            .break;\n        };\n    };\n}"
  },
  {
    "path": "WinDbg/lengthDisassembler.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\nu ${$arg1} L 1\n\nr @$t0 = 0\n\n.foreach(myVariable {u ${$arg1} L 1})\n{\n    r @$t0 = @$t0 + 1\n     \n    .if(@$t0==3)\n    {\n        .if($spat(\"${myVariable}\", \"??\")==1){.printf \"1\"}\n        .if($spat(\"${myVariable}\", \"????\")==1){.printf \"2\"}        \n        .if($spat(\"${myVariable}\", \"??????\")==1){.printf \"3\"}                \n        .if($spat(\"${myVariable}\", \"????????\")==1){.printf \"4\"}\n        .if($spat(\"${myVariable}\", \"??????????\")==1){.printf \"5\"}\n        .if($spat(\"${myVariable}\", \"????????????\")==1){.printf \"6\"}\n        .if($spat(\"${myVariable}\", \"??????????????\")==1){.printf \"7\"}\n        .if($spat(\"${myVariable}\", \"????????????????\")==1){.printf \"8\"}\n        .if($spat(\"${myVariable}\", \"??????????????????\")==1){.printf \"9\"}\n    }\n}"
  },
  {
    "path": "WinDbg/load_code_to_kernel_memory.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$ $$>a<c:\\tools\\@scripts\\windbg\\load_code_to_kernel_memory.wdbg <src code> <mem size> <offset start routine>\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload /f\n}\n\n$$set a breakpoint on a common function that is executed frequently (NtCreateFile for example) for hijacking the thread for a while\n\nba e1 nt!NtCreateFile\ng\n\n.printf \"${$arg1}\"\n.printf \"${$arg2}\"\n.printf \"${$arg3}\"\n\nbc *\n\n$$save original esp register and stack parameters that we are going to overwrite when calling ExAllocatePool and PsCreateSystemThread\n\nr @$t19 = (poi esp)\nr @$t18 = (poi esp+4)\nr @$t17 = (poi esp+8)\nr @$t16 = (poi esp+c)\nr @$t15 = (poi esp+10)\nr @$t14 = (poi esp+14)\nr @$t13 = (poi esp+18)\nr @$t12 = (poi esp+1c)\nr @$t11 = esp\n\n$$change the stack with the parameters that we need for ExAllocatePool\n\ned (esp+4) 0\ned (esp+8) ${$arg2}\n\n$$hijack the thread running on NtCreateFile to execute ExAllocatePool\n\nu nt!ExAllocatePool\ndd esp\nr eip = nt!ExAllocatePool\n\n$$steps until the ret instruction is found. We cant execute step out (gu) because we would get a 0x30 bugcheck, this is the reason:\n$$  \"This bug check occurs when there's a stack underflow detected when restoring context coming out of a trap. There's a check to \n$$  validate that the current ESP is less than the ESP saved in the trap frame. If current_esp < saved_esp, bugcheck. \"\n\n.while (1)\n{\n    p\n    r @$t10 = (poi eip)\n    r @$t10 = @$t10 & 0x000000ff\n    \n    .if (@$t10 == 0xc2)\n    {\n        .break\n    }\n}\n\nr @$t0 = eax\n\n.printf \"allocated mem: %x\\n\", @$t0\n\n$$load code from file to allocated memory\n\n$$careful: .readmem will read blocks of 0x1000 bytes. For example, if your file to load has 0x2800 bytes, .readmem will load 0x2000 bytes only. \n$$You will need to complete the file with 0x800 additional trash bytes to load the full code\n\n.readmem ${$arg1} @$t0\n\n$$ @$t1 = allocated mem membase, code is read\n\nr @$t1 = @$t0\n\n$$Now we are going to create a kernel thread at @$t1 + arg3 (membase + startroutine_offset)\n\n$$ NTSTATUS PsCreateSystemThread(\n$$   _Out_     PHANDLE            ThreadHandle,\n$$   _In_      ULONG              DesiredAccess,\n$$   _In_opt_  POBJECT_ATTRIBUTES ObjectAttributes,\n$$   _In_opt_  HANDLE             ProcessHandle,\n$$   _Out_opt_ PCLIENT_ID         ClientId,\n$$   _In_      PKSTART_ROUTINE    StartRoutine,\n$$   _In_opt_  PVOID              StartContext\n$$ );\n\ned (esp+1c) 0\ned (esp+18) @$t1+${$arg3}\ned (esp+14) 0\ned (esp+10) 0\ned (esp+c) 0\ned (esp+8) 0\n$$ThreadHandle inout, we use the memory of the parameter StartContext that we dont need\ned (esp+4) (esp+1c) \n\n$$set a breakpoint where the thread is going to be created\n\nba e1 @$t1+${$arg3}\n\nu nt!PsCreateSystemThread\ndd esp\nr eip = nt!PsCreateSystemThread\n\n$$again steps until ret instruction is found\n\n.while (1)\n{\n    p\n    r @$t10 = (poi eip)\n    r @$t10 = @$t10 & 0x000000ff\n    \n    .if (@$t10 == 0xc2)\n    {\n        .break\n    }\n}\n\n$$restore original registers and stack to continue the execution with no problems\n\nr eip = nt!NtCreateFile\nr esp = @$t11 \ned esp @$t19\ned (esp+4) @$t18\ned (esp+8) @$t17\ned (esp+c) @$t16 \ned (esp+10) @$t15 \ned (esp+14) @$t14 \ned (esp+18) @$t13 \ned (esp+1c) @$t12 \n\ng"
  },
  {
    "path": "WinDbg/load_swish.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n!load C:\\tools\\@scripts\\windbg\\SwishDbgExt-master\\Debug\\x64\\SwishDbgExt.dll"
  },
  {
    "path": "WinDbg/log_processes.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$  $$>a<log_processes.wdbg <destination directory>\n\n.logopen ${$arg1}\\log_processes.start\n.logclose\n\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.logopen ${$arg1}\\processes_wdbglog.txt\n!process 0 0\n.logclose\n\n.logopen ${$arg1}\\log_processes.end\n.logclose\n"
  },
  {
    "path": "WinDbg/monitoring_breakpoints.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$ $$>a<c:\\tools\\@scripts\\windbg\\monitoring_breakpoints.wdbg\n\n.block\n{\n    .sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n    .reload\n}\n\n$$.process /i ${$arg1}\n$$g\n\n$$.reload /user\n\n.block\n{\n    \n    bp /p ${$arg1} kernel32!CreateFileA \".printf /D \\\"<b>%x - CreateFileA('%ma')</b>\\\\n\\\", poi($csp), poi($csp+4) ; gc\"\n    bp /p ${$arg1} kernel32!CreateFileW \".printf /D \\\"<b>%x - CreateFileW('%mu')</b>\\\\n\\\", poi($csp), poi($csp+4) ; gc\"\n    \n    bp /p ${$arg1} advapi32!RegOpenKeyA \".printf /D \\\"<b>%x - RegOpenKeyA(%x,%ma)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    bp /p ${$arg1} advapi32!RegOpenKeyW \".printf /D \\\"<b>%x - RegOpenKeyW(%x,%mu)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    bp /p ${$arg1} advapi32!RegCreateKeyA \".printf /D \\\"<b>%x - RegCreateKeyA(%x,%ma)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    bp /p ${$arg1} advapi32!RegCreateKeyW \".printf /D \\\"<b>%x - RegCreateKeyW(%x,%mu)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    bp /p ${$arg1} advapi32!RegSetValueA \".printf /D \\\"<b>%x - RegSetValueA(%x,%ma)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    bp /p ${$arg1} advapi32!RegSetValueW \".printf /D \\\"<b>%x - RegSetValueW(%x,%mu)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    bp /p ${$arg1} advapi32!RegSetValueExA \".printf /D \\\"<b>%x - RegSetValueExA(%x,%ma)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    bp /p ${$arg1} advapi32!RegSetValueExW \".printf /D \\\"<b>%x - RegSetValueExW(%x,%mu)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    \n    bp /p ${$arg1} kernel32!LoadLibraryW \".printf /D \\\"<b>%x - LoadLibraryW('%mu')</b>\\\\n\\\", poi($csp), poi($csp+4) ; gc\"\n    \n    bp /p ${$arg1} kernel32!WriteProcessMemory \".printf /D \\\"<b>%x - WriteProcessMemory(%x, %x, %ma)-></b>\\\", poi($csp), poi($csp+4), poi($csp+4*2), poi($csp+3*4); $$>a<$$>a<c:\\\\tools\\\\@scripts\\\\windbg\\\\show_proc_from_handle.wdbg poi($csp+4);.printf \\\"\\\\n\\\"; gc\"\n    bp /p ${$arg1} kernel32!CreateRemoteThread \".printf /D \\\"<b>%x - CreateRemoteThread(%x, %x)-></b>\\\", poi($csp), poi($csp+4), poi($csp+4*4); $$>a<c:\\\\tools\\\\@scripts\\\\windbg\\\\show_proc_from_handle.wdbg poi($csp+4);.printf \\\"\\\\n\\\"; gc\"\n    bp /p ${$arg1} kernel32!CreateProcessA \".printf /D \\\"<b>%x - CreateProcessA(%ma,%ma)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    bp /p ${$arg1} kernel32!CreateProcessW \".printf /D \\\"<b>%x - CreateProcessW(%mu,%mu)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    \n    bp /p ${$arg1} wininet!InternetOpenA \".printf /D \\\"<b>%x - InternetOpenA()</b>\\\\n\\\", poi($csp); gc\"\n    bp /p ${$arg1} wininet!InternetOpenW \".printf /D \\\"<b>%x - InternetOpenW()</b>\\\\n\\\", poi($csp); gc\"\n    bp /p ${$arg1} wininet!InternetOpenUrlA \".printf /D \\\"<b>%x - InternetOpenA(%ma,%ma)</b>\\\\n\\\", poi($csp), poi($csp+2*4), poi($csp+3*4) ; gc\"\n    bp /p ${$arg1} wininet!InternetOpenUrlW \".printf /D \\\"<b>%x - InternetOpenW(%mu,%mu)</b>\\\\n\\\", poi($csp), poi($csp+2*4), poi($csp+3*4) ; gc\"\n    \n    $$bp /p ${$arg1} kernel32!CreateWaitableTimerW \".printf /D \\\"<b>%x - CreateWaitableTimerW('%mu')</b>\\\\n\\\", poi($csp), poi($csp+3*4) ; gc\"\n    $$bp /p ${$arg1} kernel32!GetTickCount \"$$ .printf /D \\\"<b>%x - GetTickCount()</b>\\\\n\\\" , poi($csp); r eax = 0 ; r eip = poi($csp) ; r esp = esp + 4 ; gc\"\n    $$bp /p ${$arg1} kernel32!Sleep \".printf /D \\\"<b>%x - Sleep(%ds)</b>\\\\n\\\", poi($csp), poi($csp+4)/0n1000 ; r eip = poi($csp) ; r esp = esp + 8 ; gc\"\n    \n    bp /p ${$arg1} kernel32!ExitProcess \".printf /D \\\"<b>%x - ExitProcess()</b>\\\\n\\\", poi($csp); gc\"\n    \n    bp /p ${$arg1} kernel32!VirtualProtect \".printf /D \\\"<b>%x - VirtualProtect(%p, %x, %x)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4), poi($csp+3*4) ; gc\"\n    bp /p ${$arg1} kernel32!VirtualProtectEx \".printf /D \\\"<b>%x - VirtualProtectEx(%p, %x, %x)-></b>\\\", poi($csp), poi($csp+2*4), poi($csp+3*4), poi($csp+4*4) ; $$>a<c:\\\\tools\\\\@scripts\\\\windbg\\\\show_proc_from_handle.wdbg poi($csp+4);.printf \\\"\\\\n\\\"; gc\"\n    \n    bp /p ${$arg1} advapi32!CryptGenKey \".printf /D \\\"<b>%x - CryptGenKey(%x, %x)</b>\\\\n\\\", poi($csp), poi($csp+2*4), poi($csp+3*4) ; gc\"\n    bp /p ${$arg1} advapi32!CryptImportKey \".printf /D \\\"<b>%x - CryptImportKey(%p, %x, %x)</b>\\\\n\\\", poi($csp), poi($csp+2*4), poi($csp+3*4), poi($csp+5*4); gc\"\n    bp /p ${$arg1} advapi32!CryptDecrypt \".printf /D \\\"<b>%x - CryptDecrypt(%x, %p, %p)</b>\\\\n\\\", poi($csp), poi($csp+4*4), poi($csp+5*4), poi($csp+6*4); gc\"\n    bp /p ${$arg1} advapi32!CryptEncrypt \".printf /D \\\"<b>%x - CryptEncrypt(%x, %p, %p, %x)</b>\\\\n\\\", poi($csp), poi($csp+4*4), poi($csp+5*4), poi($csp+6*4), poi($csp+7*4); gc\"\n    \n    $$bp /p ${$arg1} kernel32!CreateToolhelp32Snapshot \".printf /D \\\"<b>%x - CreateToolhelp32Snapshot(%x, %x)</b>\\\\n\\\", poi($csp), poi($csp+4), poi($csp+2*4) ; gc\"\n    $$bp /p ${$arg1} kernel32!Process32First \".printf /D \\\"<b>%x - Process32First()</b>\\\\n\\\", poi($csp); gc\"\n    $$bp /p ${$arg1} kernel32!Process32Next \".printf /D \\\"<b>%x - Process32Next()</b>\\\\n\\\", poi($csp); gc\"\n    $$bp /p ${$arg1} kernel32!Thread32First \".printf /D \\\"<b>%x - Thread32First()</b>\\\\n\\\", poi($csp); gc\"\n    $$bp /p ${$arg1} kernel32!Thread32Next \".printf /D \\\"<b>%x - Thread32Next()</b>\\\\n\\\", poi($csp); gc\"\n    $$bp /p ${$arg1} kernel32!Module32First \".printf /D \\\"<b>%x - Module32First()</b>\\\\n\\\", poi($csp); gc\"\n    $$bp /p ${$arg1} kernel32!Module32Next \".printf /D \\\"<b>%x - Module32Next()</b>\\\\n\\\", poi($csp); gc\"\n    \n    sxd sse\n    \n}"
  },
  {
    "path": "WinDbg/pagein_range.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$\n$$     $$>a<pagein_range.wdbg <start_address> <end_address> <process>\n$$\n$$ Page into memory a range of memory of the given process\n$$\n\nr $t0 = ${$arg1};\n\n.while (@$t0 < ${$arg2})\n{\n    .if($vvalid(@$t0, 1)==0)\n    {\n        .printf \"paging in: %x\\n\", @$t0\n        .pagein /p ${$arg3} @$t0\n        g\n        .if($vvalid(@$t0, 1)==0)\n        {\n            .printf \"!!!failed to page in: %x\\n\", @$t0\n        }    \n    }\n    .else\n    {\n        .printf \"already paged in: %x\\n\", @$t0\n    }\n    r $t0 = @$t0 + 0x1000;\n};"
  },
  {
    "path": "WinDbg/remove_device_acls.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\naS stage @$t19\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\nr stage = 0\n\n.foreach( tok { !devobj \"${$arg1}\" } )\n{\n    .printf \"${tok}\\r\\n\"    \n\n    .if(${stage}==1)\n    {\n        .echo ${tok}\n        dt _DEVICE_OBJECT ${tok}        \n        r $t0 = ${tok}\n        dt _SECURITY_DESCRIPTOR @@c++( ( ( nt!_DEVICE_OBJECT * ) @$t0 )->SecurityDescriptor )\n        \n        ep @@c++( ( ( nt!_DEVICE_OBJECT * ) @$t0 )->SecurityDescriptor ) + @@c++( #FIELD_OFFSET( _SECURITY_DESCRIPTOR, Sacl ) ) 0\n        ep @@c++( ( ( nt!_DEVICE_OBJECT * ) @$t0 )->SecurityDescriptor ) + @@c++( #FIELD_OFFSET( _SECURITY_DESCRIPTOR, Dacl ) ) 0\n        \n        dt _SECURITY_DESCRIPTOR @@c++( ( ( nt!_DEVICE_OBJECT * ) @$t0 )->SecurityDescriptor )\n        \n        .break\n    }    \n    \n    .if(${stage}==0)\n    {\n        .if($scmp(\"${tok}\",\"object\")==0)\n        {\n            r stage = 1\n        }\n    }\n}\n\n"
  },
  {
    "path": "WinDbg/search_bytes_all_processes.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<search_bytes_all_processes.wdbg <byte1> <byte2> ... <byteN>       (max 16 bytes)\n$$\n$$ This script is useful for search a max of 16 given bytes through all the running processes\n$$\n\naS stage @$t19\naS temp @$t18\naS baseSearch @$t17\naS stop @$t16\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    r stage = 2\n    \n    .foreach (processes_tok { !process 0 0 })\n    {\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Analyzing process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n        \n            .process /i ${processes_tok}\n            g\n            \n            .block\n            {\n                .reload\n            }\n            \n            .block\n            {\n                .reload /user\n            }\n        \n            r ${stop} = 0\n            r ${baseSearch} = 0\n        \n            .while(${stop} == 0)\n            {\n                .printf \"searching base %x\\n\", ${baseSearch}\n                \n                r @$t0 = ${baseSearch}\n                \n                s @$t0 L?0x10000000 ${$arg1} ${$arg2} ${$arg3} ${$arg4} ${$arg5} ${$arg6} ${$arg7} ${$arg8} ${$arg9} ${$arg10} ${$arg11} ${$arg12} ${$arg13} ${$arg14} ${$arg15} ${$arg16}\n                \n                .if(${baseSearch} >= 0x70000000)\n                {\n                    .printf \"next process\\n\"\n                    r ${stop} = 1\n                }\n                \n                r ${baseSearch} = ${baseSearch} + 0x10000000            \n            }\n        }    \n    }\n\n    ad stage\n    ad temp\n    ad baseSearch\n    ad stop\n}"
  },
  {
    "path": "WinDbg/search_bytes_target_process.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<search_string_target_process.wdbg <proc> <byte1> <byte2> .. <byteN>\n$$\n$$ This script is useful for search a max of 16 given bytes in the given process\n$$     \n\naS baseSearch @$t17\naS stop @$t16\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    .process /i ${$arg1}\n    g\n    \n    .block\n    {\n        .reload\n    }\n    \n    .block\n    {\n        .reload /user\n    }\n    \n    r ${stop} = 0\n    r ${baseSearch} = 0\n    \n    .while(${stop} == 0)\n    {\n        .printf \"searching base %x\\n\", ${baseSearch}\n        \n        r @$t0 = ${baseSearch}\n        \n        s @$t0 L?0x10000000 ${$arg2} ${$arg3} ${$arg4} ${$arg5} ${$arg6} ${$arg7} ${$arg8} ${$arg9} ${$arg10} ${$arg11} ${$arg12} ${$arg13} ${$arg14} ${$arg15} ${$arg16} ${$arg17}\n        \n        .if(${baseSearch} >= 0x70000000)\n        {\n            r ${stop} = 1\n        }\n        \n        r ${baseSearch} = ${baseSearch} + 0x10000000            \n    }\n\n    ad baseSearch\n    ad stop\n}"
  },
  {
    "path": "WinDbg/search_string_all_processes.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<search_string_all_processes.wdbg <string>\n$$\n$$ This script is useful for search a given string through all the running processes\n$$\n\naS stage @$t19\naS temp @$t18\naS baseSearch @$t17\naS stop @$t16\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    r stage = 2\n    \n    .foreach (processes_tok { !process 0 0 })\n    {\n        .if($scmp(\"${processes_tok}\",\"PROCESS\")==0)\n        {\n            .if(${stage}==2)\n            {\n                $$stage==2 is used to skip the first apparition of PROCESS string in the results of !process 0 0\n                r stage = 0\n            }\n            .else\n            {            \n                r stage = 1\n            }\n        }\n        .elsif(${stage}==1)\n        {\n            .printf /D \"<b>Analyzing process ${processes_tok}</b>\\n\"\n            \n            r stage = 0\n        \n            .process /i ${processes_tok}\n            g\n            \n            .block\n            {\n                .reload\n            }\n            \n            .block\n            {\n                .reload /user\n            }\n        \n            r ${stop} = 0\n            r ${baseSearch} = 0\n        \n            .while(${stop} == 0)\n            {\n                .printf \"searching base %x\\n\", ${baseSearch}\n                \n                r @$t0 = ${baseSearch}\n                \n                s -a @$t0 L?0x10000000 \"${$arg1}\"\n                \n                .if(${baseSearch} >= 0x70000000)\n                {\n                    .printf \"next process\\n\"\n                    r ${stop} = 1\n                }\n                \n                r ${baseSearch} = ${baseSearch} + 0x10000000            \n            }\n        }    \n    }\n\n    ad stage\n    ad temp\n    ad baseSearch\n    ad stop\n}"
  },
  {
    "path": "WinDbg/search_string_target_process.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<search_string_target_process.wdbg <proc> <string> \n$$\n$$ This script is useful for search a given string in a given process\n$$\n\naS baseSearch @$t17\naS stop @$t16\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.block\n{\n    .process /i ${$arg1}\n    g\n    \n    .block\n    {\n        .reload\n    }\n    \n    .block\n    {\n        .reload /user\n    }\n    \n    r ${stop} = 0\n    r ${baseSearch} = 0\n    \n    .while(${stop} == 0)\n    {\n        .printf \"searching base %x\\n\", ${baseSearch}\n        \n        r @$t0 = ${baseSearch}\n        \n        s -a @$t0 L?0x10000000 \"${$arg2}\"\n        \n        .if(${baseSearch} >= 0x70000000)\n        {\n            r ${stop} = 1\n        }\n        \n        r ${baseSearch} = ${baseSearch} + 0x10000000            \n    }\n\n    ad baseSearch\n    ad stop\n}"
  },
  {
    "path": "WinDbg/secure_writemem.wdbg",
    "content": "$$\r\n$$ Author: Javier Vicente Vallejo\r\n$$ Twitter: @vallejocc\r\n$$ Web: http://www.vallejo.cc\r\n$$\r\n$$     $$>a<secure_writemem.wdbg <start> <end> <process> <targetdir> <ext>\r\n$$\r\n$$ this script tries to dump a range of memory. If its not possible to dump a part of the range, that part if filled with random data\r\n$$ (really its filled with \"\\x11\\x11\\x11......\\x11\\x20\\x0d\\x0a\" (total length 0x1000 for each page filled), but we must not assume it \r\n$$ will always contain this value \r\n\r\n.printf \"secure_writemem.wdbg\\r\\n\"\r\n.printf \"${$arg1}\\r\\n\"\r\n.printf \"${$arg2}\\r\\n\"\r\n.printf \"${$arg3}\\r\\n\"\r\n.printf \"${$arg4}\\r\\n\"\r\n.printf \"${$arg5}\\r\\n\"\r\n\r\naS swmbase @$t18\r\naS swmend @$t17\r\naS swmtemp @$t16\r\n\r\n.block\r\n{\r\n    .printf \"secure_writemem_1\\r\\n\"\r\n\r\n    r ${swmbase} = ${$arg1}\r\n    r ${swmend} = ${$arg2}\r\n    r ${swmtemp} = ${swmbase}\r\n\r\n    .printf \"secure_writemem_2\\r\\n\"\r\n\r\n    .foreach /pS 4 (swmlen_tok { ? (${swmend}-${swmbase}) })\r\n    {\r\n        .printf \"secure_writemem_3\\r\\n\"\r\n        \r\n        .block\r\n        {\r\n            .shell -x del ${$arg4}\\${$arg3}_${$arg1}_${swmlen_tok}.${$arg5}\r\n        }\r\n        \r\n        .printf \"secure_writemem_4\\r\\n\"\r\n        \r\n        .while (${swmtemp} < ${swmend})\r\n        {\r\n            .printf \"paging in: %x\\n\", ${swmtemp}\r\n            .pagein /p ${$arg3} ${swmtemp}\r\n            g\r\n            \r\n            .foreach /pS 4 (swmtemp_tok { ? swmtemp })\r\n            {   \r\n                .printf \"secure_writemem_temp_${swmtemp_tok}.bin > ${$arg3}_${$arg1}_${len_tok}.${$arg5}\\n\"\r\n                .if($vvalid(${swmtemp}, 0x1000)==1)\r\n                {\r\n                    .writemem ${$arg4}\\secure_writemem_temp_${swmtemp_tok}.bin ${swmtemp} L 0x1000\r\n                    .shell -x type ${$arg4}\\secure_writemem_temp_${swmtemp_tok}.bin >> ${$arg4}\\${$arg3}_${$arg1}_${swmlen_tok}.${$arg5} && del ${$arg4}\\secure_writemem_temp_${swmtemp_tok}.bin\r\n                }\r\n                .else\r\n                {\r\n                    .printf \"invalid address: %x\\n\", ${swmtemp}\r\n                    \r\n                    .shell -x echo \u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011\u0011 >> ${$arg4}\\${$arg3}_${$arg1}_${swmlen_tok}.${$arg5} && x\r\n                    \r\n                }\r\n            }\r\n            r ${swmtemp} = ${swmtemp} + 0x1000\r\n        }\r\n        \r\n        .printf \"secure_writemem_5\\r\\n\"\r\n    }\r\n\r\n}\r\n\r\n.printf \"secure_writemem_6\\r\\n\"\r\n"
  },
  {
    "path": "WinDbg/show_address_info.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<show_address_info.wdbg <address> <process>\n$$\n\naS stage @$t19\naS basealloc @$t18\naS stop @$t17\naS baseSearch @$t16\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n    .process /i ${$arg2}\n    g\n    .reload\n}\n\n.block\n{\n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$print info related to the address\n    \n    .printf /D \"<b>\\nAddress info for address %x</b>\\n\", ${$arg1}\n    .printf /D \"<b>--------------------------------------------</b>\\n\"\n    \n    !address ${$arg1}\n    \n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$print info related to the heap (if the address belongs to a heap)\n    \n    .printf /D \"<b>\\nHeap related info to address %x</b>\\n\", ${$arg1}\n    .printf /D \"<b>--------------------------------------------</b>\\n\"\n    \n    !heap -p -a ${$arg1}\n    \n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$search for references to the arg1 address\n    \n    .printf /D \"<b>\\nReferences to address %x</b>\\n\", ${$arg1}\n    .printf /D \"<b>--------------------------------------------</b>\\n\"\n    \n    r ${stop} = 0\n    r ${baseSearch} = 0\n    \n    .while(${stop} == 0)\n    {\n        $$.printf \"searching %x\\n\", ${baseSearch}\n        \n        r @$t0 = ${baseSearch}\n        r @$t1 = ${$arg1}\n        \n        s @$t0 L 10000000 (@$t1 & ff) ((@$t1 & ff00) >> 8) ((@$t1 & ff0000) >> 10) ((@$t1 & ff000000) >> 18)\n        \n        .if(${baseSearch} >= 0x70000000)\n        {\n            r ${stop} = 1\n        }\n        \n        r ${baseSearch} = ${baseSearch} + 10000000\n    }\n    \n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$ use !heap extension to guess the base of the allocated memory related to the arg1 address\n    \n    r stage = 0\n    r basealloc = -1\n    \n    .foreach ( tok {!heap -p -a ${$arg1}} )\n    {\n        .if(${stage} == 2)\n        {\n            r basealloc = ${tok}\n            .break\n        }\n        \n        .if(${stage} == 1)\n        {\n            .if($scmp(\"${tok}0\",\"state0\")==0)\n            {\n                r stage = 2\n            }        \n        }\n    \n        .if(${stage} == 0)\n        {\n            .if($scmp(\"${tok}0\",\"HEAP_ENTRY0\")==0)\n            {   \n                r stage = 1\n            }\n        }\n    }\n    \n    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n    $$search for references to the allocated memory base\n    \n    .if(${basealloc} != -1)\n    {\n        .printf /D \"<b>\\nReferences to allocation base %x</b>\\n\", ${basealloc}+8\n        .printf /D \"<b>--------------------------------------------</b>\\n\"\n            \n        r ${stop} = 0\n        r ${baseSearch} = 0\n        \n        .while(${stop} == 0)\n        {\n            $$.printf \"searching %x\\n\", ${baseSearch}\n            \n            r @$t0 = ${baseSearch}\n            r @$t1 = ${basealloc}+8\n            \n            s @$t0 L 10000000 (@$t1 & ff) ((@$t1 & ff00) >> 8) ((@$t1 & ff0000) >> 10) ((@$t1 & ff000000) >> 18)\n            \n            .if(${baseSearch} >= 70000000)\n            {\n                r ${stop} = 1\n            }\n            \n            r ${baseSearch} = ${baseSearch} + 10000000            \n        }\n    }\n\n    ad stage\n    ad basealloc\n    ad stop\n    ad baseSearch\n}"
  },
  {
    "path": "WinDbg/show_pe_headers.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<c:\\tools\\@scripts\\windbg\\show_pe_headers.wdbg <base_address> <process>\n\n$$.sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n$$.reload\n\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n$$ change the context to the target process and page in the page containing PE headers\n.process /i ${$arg2}\ng\n$$.reload /user\n.pagein /p ${$arg2} ${$arg1}\ng\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n$$ define some useful aliases\n\nad /q ${/v:$imagebase};\nad /q ${/v:$pe_header};\nad /q ${/v:$file_header};\nad /q ${/v:$optional_header};\nad /q ${/v:$number_of_sections};\nad /q ${/v:$sections};\n\naS /x ${/v:$imagebase} ( ${$arg1} )\naS /x ${/v:$pe_header} ( $imagebase + ( poi( $imagebase + @@( #FIELD_OFFSET( nt!_IMAGE_DOS_HEADER, e_lfanew ) ) ) ) )\naS /x ${/v:$file_header} ( $pe_header + @@( #FIELD_OFFSET( nt!_IMAGE_NT_HEADERS, FileHeader ) ) )\naS /x ${/v:$optional_header} ( $pe_header + @@( #FIELD_OFFSET( nt!_IMAGE_NT_HEADERS, OptionalHeader ) ) )\naS /x ${/v:$number_of_sections} ( poi ( $file_header + @@( #FIELD_OFFSET( nt!_IMAGE_FILE_HEADER, NumberOfSections ) ) ) & 0xffff )\naS /x ${/v:$data_directory} ( $optional_header + @@( #FIELD_OFFSET( nt!_IMAGE_OPTIONAL_HEADER, DataDirectory ) ) )\naS /x ${/v:$sections} ( $pe_header + @@c++( sizeof ( nt!_IMAGE_NT_HEADERS ) ) )\n\n.printf \"DOS HEADER:\\n\"\n.printf \"----------:\\n\"\ndt nt!_IMAGE_DOS_HEADER $imagebase\n.printf \"NT HEADERS:\\n\"\n.printf \"----------:\\n\"\ndt nt!_IMAGE_NT_HEADERS $pe_header\n.printf \"FILE HEADER:\\n\"\n.printf \"-----------:\\n\"\ndt nt!_IMAGE_FILE_HEADER $file_header\n.printf \"OPTIONAL HEADER:\\n\"\n.printf \"---------------:\\n\"\ndt nt!_IMAGE_OPTIONAL_HEADER $optional_header\n.printf \"DATA DIRECTORY 0 EXPORT:\\n\"\n.printf \"-----------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 0\n.printf \"DATA DIRECTORY 1 IMPORT:\\n\"\n.printf \"-----------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 1\n.printf \"DATA DIRECTORY 2 RESOURCE:\\n\"\n.printf \"-------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 2\n.printf \"DATA DIRECTORY 3 EXCEPTION:\\n\"\n.printf \"--------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 3\n.printf \"DATA DIRECTORY 4 SECURITY:\\n\"\n.printf \"-------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 4\n.printf \"DATA DIRECTORY 5 FIXUPS:\\n\"\n.printf \"-----------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 5\n.printf \"DATA DIRECTORY 6 DEBUG:\\n\"\n.printf \"----------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 6\n.printf \"DATA DIRECTORY 7 DESCRIPTION:\\n\"\n.printf \"----------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 7\n.printf \"DATA DIRECTORY 8 MIPS GP:\\n\"\n.printf \"------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 8\n.printf \"DATA DIRECTORY 9 TLS:\\n\"\n.printf \"--------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 9\n.printf \"DATA DIRECTORY 10 LOAD CONFIG:\\n\"\n.printf \"-----------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 10\n.printf \"DATA DIRECTORY 11 BOUND IMPORT:\\n\"\n.printf \"------------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 11\n.printf \"DATA DIRECTORY 12 IMPORT TABLE:\\n\"\n.printf \"------------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 12\n.printf \"DATA DIRECTORY 13 DELAY IMPORT:\\n\"\n.printf \"------------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 13\n.printf \"DATA DIRECTORY 14 COM RUNTIME:\\n\"\n.printf \"-----------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 14\n.printf \"DATA DIRECTORY 15 RESERVED:\\n\"\n.printf \"--------------------------:\\n\"\ndt nt!_IMAGE_DATA_DIRECTORY $data_directory + @@c++( sizeof ( nt!_IMAGE_DATA_DIRECTORY ) ) * 15\nr $t0 = $sections\nr $t1 = 0\nr $t2 = $number_of_sections\n.while (@$t1 < @$t2)\n{\n    .printf \"SECTION HEADER %d:\\n\", @$t1\n    .printf \"-----------------:\\n\"\n    r $t3 = $sections + @$t1 * @@c++(sizeof(nt!_IMAGE_SECTION_HEADER))\n    dt -b nt!_IMAGE_SECTION_HEADER @$t3\n    r $t1 = @$t1 + 1\n}"
  },
  {
    "path": "WinDbg/show_proc_from_handle.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<show_proc_from_handle.wdbg <handle>\n$$\n\n$$.sympath SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\n$$.reload\n\n\nr @$t0 = ${$arg1}\n\n.if(@$t0!=0 & @$t0!=0xffffffff)\n{\n    r @$t1 = 0;\n    .foreach (tok { !handle @$t0 })\n    {\n        .if(@$t1==1)\n        {\n            r @$t1 = 0;\n            .printf /D \"<b>${tok} \"\n            .foreach (tok2 { !process ${tok} 0 })\n            {\n                .if(@$t1==1)\n                {\n                    .printf /D \"${tok2}\\n</b>\"\n                    .break;\n                }\n                .elsif($scmp(\"${tok2}\",\"Image:\")==0)\n                {\n                    r @$t1 = 1;\n                }            \n            }            \n            .break;                \n        }\n        .elsif($scmp(\"${tok}\",\"Object:\")==0)\n        {\n            r @$t1 = 1;\n        };\n    };\n};\n"
  },
  {
    "path": "WinDbg/symbols.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n$$     $$>a<symbols.wdbg\n$$\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*https://msdl.microsoft.com/download/symbols;SRV*c:\\symcache*https://chromium-browser-symsrv.commondatastorage.googleapis.com;SRV*c:\\symcache\\*https://symbols.mozilla.org/\";\n    .reload\n}\n\n\n"
  },
  {
    "path": "WinDbg/write_mem_dump.wdbg",
    "content": "$$\n$$ Author: Javier Vicente Vallejo\n$$ Twitter: @vallejocc\n$$ Web: http://www.vallejo.cc\n$$\n\n$$  $$>a<write_mem_dump.wdbg <destination directory>\n\n.logopen ${$arg1}\\write_mem_dump.start\n.logclose\n\n\n.block\n{\n    .sympath \"SRV*c:\\symcache*http://msdl.microsoft.com/download/symbols\";\n    .reload\n}\n\n.dump /f ${$arg1}\\memory.dmp\n\n.logopen ${$arg1}\\write_mem_dump.end\n.logclose\n"
  }
]