├── .gitattributes ├── jsm.asm └── jsm.inc /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /jsm.asm: -------------------------------------------------------------------------------- 1 | bits32 2 | 3 | %include "jsm.inc" 4 | 5 | ;scripthost db "JScript\CLSID", 0 6 | 7 | krnnames db "LoadLibraryA", 0 8 | 9 | olenames db "CoCreateInstance", 0 10 | db "CoInitializeEx" , 0 11 | db "CoUninitialize" , 0 12 | 13 | global _main 14 | section .text 15 | _main: 16 | push ebx 17 | mov edx, comcrcstk_size >> 2 18 | mov ebx, olenames 19 | mov edi, comcrcbegin 20 | call create_crcs 21 | mov edx, krncrcstk_size >> 2 22 | mov ebx, krnnames 23 | mov edi, krncrcbegin 24 | call create_crcs 25 | pop ebx 26 | jmp entry 27 | 28 | create_crcs: 29 | or eax, -1 30 | 31 | create_outer: 32 | xor al, byte [ebx] 33 | push 8 34 | pop ecx 35 | 36 | create_inner: 37 | shr eax, 1 38 | jnc create_skip 39 | xor eax, 0edb88320h 40 | 41 | create_skip: 42 | loop create_inner 43 | inc ebx 44 | cmp byte [ebx], cl 45 | jne create_outer 46 | not eax 47 | stosd 48 | inc ebx 49 | dec edx 50 | jne create_crcs 51 | ret 52 | 53 | ;----------------------------------------------------------------------------- 54 | ;this is the entry 55 | ;----------------------------------------------------------------------------- 56 | 57 | entry: 58 | xor eax, eax 59 | 60 | ;disabled for fast fail 61 | 62 | ; fs push dword [eax] 63 | ; fs mov dword [eax], esp 64 | call init_kernel32 65 | 66 | ;----------------------------------------------------------------------------- 67 | ;API CRC table, null terminated 68 | ;----------------------------------------------------------------------------- 69 | 70 | krncrcbegin: 71 | times krncrcstk_size >> 2 dd 0 72 | db 0 73 | 74 | ;----------------------------------------------------------------------------- 75 | ;get OLE32 APIs 76 | ;----------------------------------------------------------------------------- 77 | 78 | call load_fwdll 79 | db "api-ms-win-core-com-l1-1-1", 0 80 | ;forwarder chain from ole32.dll 81 | load_fwdll: 82 | call load_ole32 83 | db "ole32", 0 84 | 85 | load_ole32: 86 | call dword [esp + 8 + krncrcstk.kLoadLibraryA] 87 | xchg ebp, eax 88 | call dword [esp + 4 + krncrcstk.kLoadLibraryA] 89 | test eax, eax 90 | cmovne ebp, eax 91 | call parse_exports 92 | 93 | ;----------------------------------------------------------------------------- 94 | ;API CRC table, null terminated 95 | ;----------------------------------------------------------------------------- 96 | 97 | comcrcbegin: 98 | times comcrcstk_size >> 2 dd 0 99 | db 0 100 | 101 | mov ebp, esp 102 | 103 | ;----------------------------------------------------------------------------- 104 | ;initialize IActiveScript, IActiveScriptParser support 105 | ;----------------------------------------------------------------------------- 106 | 107 | xor ebx, ebx 108 | push ebx 109 | push esp 110 | call skip_iid 111 | db 0e1h, 02ah, 01ah, 0bbh, 0f9h, 0a4h, 0cfh, 011h, 08fh, 020h, 000h, 080h, 05fh, 02ch, 0d0h, 064h 112 | 113 | skip_iid: 114 | pop edi 115 | push edi 116 | push CLSCTX_INPROC_SERVER 117 | push ebx 118 | call skip_guid 119 | db 060h, 0c2h, 014h, 0f4h, 0c0h, 06ah, 0cfh, 011h, 0b6h, 0d1h, 000h, 0aah, 000h, 0bbh, 0bbh, 058h 120 | 121 | skip_guid: 122 | push COINIT_APARTMENTTHREADED 123 | push ebx 124 | call dword [ebp + comcrcstk.oCoInitializeEx] 125 | call dword [ebp + comcrcstk.oCoCreateInstance] 126 | pop esi 127 | push ebx 128 | push esp 129 | inc dword [edi] ;RIIDs differ by one bit 130 | push edi 131 | push esi 132 | mov eax, dword [esi] 133 | call dword [eax + IActiveScript_vtable.iaQueryInterface] 134 | dec dword [edi] ;restore bit 135 | 136 | ;----------------------------------------------------------------------------- 137 | ;initialize new script engine 138 | ;----------------------------------------------------------------------------- 139 | 140 | pop edi 141 | push edi 142 | mov eax, dword [edi] 143 | call dword [eax + IActiveScriptParse32_vtable.iaInitNew] 144 | call skip_methods 145 | 146 | methods_table: 147 | 148 | ;----------------------------------------------------------------------------- 149 | ;HRESULT (STDMETHODCALLTYPE *QueryInterface)(IActiveScriptSite *this, REFIID riid, void **ppvObject); 150 | ;----------------------------------------------------------------------------- 151 | 152 | mQueryInterface: 153 | mov eax, E_NOTIMPL 154 | retn 0ch 155 | 156 | ;----------------------------------------------------------------------------- 157 | ;ULONG (STDMETHODCALLTYPE *AddRef)(IActiveScriptSite *this); 158 | ;ULONG (STDMETHODCALLTYPE *Release)(IActiveScriptSite *this); 159 | ;HRESULT (STDMETHODCALLTYPE *OnEnterScript)(IActiveScriptSite *this); 160 | ;HRESULT (STDMETHODCALLTYPE *OnLeaveScript)(IActiveScriptSite *this); 161 | ;----------------------------------------------------------------------------- 162 | 163 | mAddRef: 164 | mRelease: 165 | mOnEnterScript: 166 | mOnLeaveScript: 167 | xor eax, eax 168 | retn 4 169 | 170 | ;----------------------------------------------------------------------------- 171 | ;HRESULT (STDMETHODCALLTYPE *GetLCID)(IActiveScriptSite *this, LCID *plcid); 172 | ;HRESULT (STDMETHODCALLTYPE *GetDocVersionString)(IActiveScriptSite *this, BSTR *pbstrVersion); 173 | ;----------------------------------------------------------------------------- 174 | 175 | mGetLCID: 176 | mGetDocVersionString: 177 | mov eax, E_NOTIMPL 178 | retn 8 179 | 180 | ;----------------------------------------------------------------------------- 181 | ;HRESULT (STDMETHODCALLTYPE *OnScriptTerminate)(IActiveScriptSite *this, const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo); 182 | ;----------------------------------------------------------------------------- 183 | 184 | mOnScriptTerminate: 185 | xor eax, eax 186 | retn 0ch 187 | 188 | ;----------------------------------------------------------------------------- 189 | ;HRESULT (STDMETHODCALLTYPE *OnStateChange)(IActiveScriptSite *this, SCRIPTSTATE ssScriptState); 190 | ;HRESULT (STDMETHODCALLTYPE *OnScriptError)(IActiveScriptSite *this, IActiveScriptError *pscripterror); 191 | ;----------------------------------------------------------------------------- 192 | 193 | mOnStateChange: 194 | mOnScriptError: 195 | xor eax, eax 196 | retn 8 197 | 198 | ;----------------------------------------------------------------------------- 199 | ;create virtual table in stack 200 | ;----------------------------------------------------------------------------- 201 | 202 | skip_methods: 203 | pop eax 204 | lea edx, dword [eax + mOnLeaveScript - methods_table] 205 | push edx 206 | push edx ;OnEnterScript 207 | lea ecx, dword [eax + mOnScriptError - methods_table] 208 | push ecx 209 | push ecx ;OnStateChange 210 | lea ecx, dword [eax + mOnScriptTerminate - methods_table] 211 | push ecx 212 | lea ecx, dword [eax + mGetDocVersionString - methods_table] 213 | push ecx 214 | push ebx ;GetItemInfo 215 | push ecx ;GetLCID 216 | push edx ;Release 217 | push edx ;AddRef 218 | push eax ;QueryInterface 219 | push esp ;vtbl 220 | push esp 221 | push esi 222 | mov eax, dword [esi] 223 | call dword [eax + IActiveScript_vtable.iaSetScriptSite] 224 | push ebx 225 | push ebx 226 | push SCRIPTTEXT_ISEXPRESSION 227 | push ebx 228 | push ebx 229 | push ebx 230 | push ebx 231 | push ebx 232 | call skip_script 233 | dw "n", "e", "w", " ", "A", "c", "t", "i", "v", "e", "X", "O", "b", "j", "e", "c", "t" 234 | dw "(", '"', "W", "S", "c", "r", "i", "p", "t", ".", "S" , "h", "e", "l", "l", '"', ")" 235 | dw ".", "P", "o", "p", "u", "p", "(", '"', "H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d", '"', ")", 0; 236 | 237 | skip_script: 238 | push edi 239 | mov eax, dword [edi] 240 | call dword [eax + IActiveScriptParse32_vtable.iaParseScriptText] 241 | push SCRIPTSTATE_CONNECTED 242 | push esi 243 | mov eax, dword [esi] 244 | call dword [eax + IActiveScript_vtable.iaSetScriptState] 245 | push edi 246 | mov eax, dword [edi] 247 | call dword [eax + IActiveScriptParse32_vtable.iaRelease] 248 | push esi 249 | mov eax, dword [esi] 250 | call dword [eax + IActiveScript_vtable.iaRelease] 251 | 252 | ;toDo: 253 | ;release all here 254 | int3 255 | 256 | init_kernel32: 257 | mov eax, dword [ebx + pebLdr] ;ebx = fs:[30h] at start time 258 | mov esi, dword [eax + ldrInLoadOrderModuleList] 259 | lodsd 260 | xchg esi, eax 261 | lodsd 262 | mov ebp, dword [eax + mlDllBase] 263 | 264 | ;----------------------------------------------------------------------------- 265 | ;parse export table 266 | ;----------------------------------------------------------------------------- 267 | 268 | parse_exports: 269 | pop esi 270 | mov ebx, ebp 271 | mov eax, dword [ebp + mzhdr.mzlfanew] 272 | add ebx, dword [ebp + eax + pehdr.peexport + pedir.dirrva] 273 | cdq 274 | 275 | walk_names: 276 | mov eax, ebp 277 | mov edi, ebp 278 | inc edx 279 | add eax, dword [ebx + peexp.expnamerva] 280 | add edi, dword [eax + edx * 4] 281 | or eax, -1 282 | 283 | crc_outer: 284 | xor al, byte [edi] 285 | push 8 286 | pop ecx 287 | 288 | crc_inner: 289 | shr eax, 1 290 | jnc crc_skip 291 | xor eax, 0edb88320h 292 | 293 | crc_skip: 294 | loop crc_inner 295 | inc edi 296 | cmp byte [edi], cl 297 | jne crc_outer 298 | not eax 299 | cmp dword [esi], eax 300 | jne walk_names 301 | 302 | ;----------------------------------------------------------------------------- 303 | ;exports must be sorted alphabetically, otherwise GetProcAddress() would fail 304 | ;this allows to push addresses onto the stack, and the order is known 305 | ;----------------------------------------------------------------------------- 306 | 307 | mov edi, ebp 308 | mov eax, ebp 309 | add edi, dword [ebx + peexp.expordrva] 310 | movzx edi, word [edi + edx * 2] 311 | add eax, dword [ebx + peexp.expadrrva] 312 | mov eax, dword [eax + edi * 4] 313 | add eax, ebp 314 | push eax 315 | lodsd 316 | sub cl, byte [esi] 317 | jnz walk_names 318 | inc esi 319 | jmp esi -------------------------------------------------------------------------------- /jsm.inc: -------------------------------------------------------------------------------- 1 | pebImageBase equ 8 2 | pebLdr equ 0ch 3 | ldrInLoadOrderModuleList equ 0ch 4 | mlDllBase equ 18h 5 | 6 | IActiveScript_QueryInterface equ 0 7 | AddRef equ 8 8 | 9 | CLSCTX_INPROC_SERVER equ 1 10 | 11 | COINIT_APARTMENTTHREADED equ 2 12 | 13 | E_NOINTERFACE equ 80004002h 14 | E_NOTIMPL equ 80004001h 15 | 16 | SCRIPTTEXT_ISEXPRESSION equ 20h 17 | 18 | SCRIPTSTATE_CONNECTED equ 2 19 | 20 | struc IActiveScript_vtable 21 | .iaQueryInterface: resd 1 22 | .iaAddRef: resd 1 23 | .iaRelease: resd 1 24 | .iaSetScriptSite: resd 1 25 | .iaGetScriptSite: resd 1 26 | .iaSetScriptState: resd 1 27 | .iaGetScriptState: resd 1 28 | .iaClose: resd 1 29 | endstruc 30 | 31 | struc IActiveScriptParse32_vtable 32 | .iaQueryInterface: resd 1 33 | .iaAddRef: resd 1 34 | .iaRelease: resd 1 35 | .iaInitNew: resd 1 36 | .iaAddScriptlet: resd 1 37 | .iaParseScriptText: resd 1 38 | ends 39 | 40 | struc comcrcstk 41 | .oCoUninitialize: resd 1 42 | .oCoInitializeEx: resd 1 43 | .oCoCreateInstance: resd 1 44 | endstruc 45 | 46 | struc krncrcstk 47 | .kLoadLibraryA: resd 1 48 | endstruc 49 | 50 | struc mzhdr 51 | .mzsig : resw 1 ;00 52 | .mzpagemod : resw 1 ;02 53 | .mzpagediv : resw 1 ;04 54 | .mzrelocs : resw 1 ;06 55 | .mzhdrsize : resw 1 ;08 56 | .mzminalloc: resw 1 ;0A 57 | .mzmaxalloc: resw 1 ;0C 58 | .mzss : resw 1 ;0E 59 | .mzsp : resw 1 ;10 60 | .mzchksum : resw 1 ;12 61 | .mzip : resw 1 ;14 62 | .mzcs : resw 1 ;16 63 | .mzreloff : resw 1 ;18 64 | .mzfiller : resb 22h ;1A 65 | .mzlfanew : resd 1 ;3C 66 | endstruc 67 | 68 | struc coffhdr 69 | .pemachine : resw 1 ;04 70 | .pesectcount : resw 1 ;06 71 | .petimedate : resd 1 ;08 72 | .pesymbrva : resd 1 ;0C 73 | .pesymbcount : resd 1 ;10 74 | .peopthdrsize: resw 1 ;14 75 | .peflags : resw 1 ;16 76 | endstruc 77 | 78 | struc pedir 79 | .dirrva : resd 1 80 | .dirsize: resd 1 81 | endstruc 82 | 83 | struc pehdr 84 | .pesig : resd 1 ;000 85 | .pecoff : resb coffhdr_size 86 | .pemagic : resw 1 ;018 87 | .pemajorlink : resb 1 ;01A 88 | .peminorlink : resb 1 ;01B 89 | .pecodesize : resd 1 ;01C 90 | .peidatasize : resd 1 ;020 91 | .peudatasize : resd 1 ;024 92 | .peentrypoint : resd 1 ;028 93 | .pecodebase : resd 1 ;02C 94 | .pedatabase : resd 1 95 | .peimagebase : resd 1 ;030 96 | .pesectalign : resd 1 ;038 97 | .pefilealign : resd 1 ;03C 98 | .pemajoros : resw 1 ;040 99 | .peminoros : resw 1 ;042 100 | .pemajorimage : resw 1 ;044 101 | .peminorimage : resw 1 ;046 102 | .pemajorsubsys: resw 1 ;048 103 | .peminorsubsys: resw 1 ;04A 104 | .pereserved : resd 1 ;04C 105 | .peimagesize : resd 1 ;050 106 | .pehdrsize : resd 1 ;054 107 | .pechksum : resd 1 ;058 108 | .pesubsys : resw 1 ;05C 109 | .pedllflags : resw 1 ;05E 110 | .pestackmax : resd 1 ;060 111 | .pestacksize : resd 1 ;068 112 | .peheapmax : resd 1 ;070 113 | .peheapsize : resd 1 ;078 114 | .peldrflags : resd 1 ;080 115 | .pervacount : resd 1 ;084 116 | .peexport : resb pedir_size ;088 117 | .peimport : resb pedir_size ;090 118 | .persrc : resb pedir_size ;098 119 | .peexcpt : resb pedir_size ;0A0 120 | .pesecurity : resb pedir_size ;0A8 121 | .pereloc : resb pedir_size ;0B0 122 | .pedebug : resb pedir_size ;0B8 123 | .pearch : resb pedir_size ;0C0 124 | .peglobal : resb pedir_size ;0C8 125 | .petls : resb pedir_size ;0D0 126 | .peconfig : resb pedir_size ;0D8 127 | .pebound : resb pedir_size ;0E0 128 | .peiat : resb pedir_size ;0E8 129 | .pedelay : resb pedir_size ;0F0 130 | .pecom : resb pedir_size ;0F8 131 | .persrv : resb pedir_size 132 | endstruc 133 | 134 | struc peexp 135 | .expflags : resd 1 136 | .expdatetime : resd 1 137 | .expmajorver : resw 1 138 | .expminorver : resw 1 139 | .expdllrva : resd 1 140 | .expordbase : resd 1 141 | .expadrcount : resd 1 142 | .expnamecount: resd 1 143 | .expadrrva : resd 1 144 | .expnamerva : resd 1 145 | .expordrva : resd 1 146 | endstruc --------------------------------------------------------------------------------