// // // #define NULL 0 typedef unsigned char byte; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned __int64 ulong; #pragma pack(1) typedef struct _GDTR { ushort Limit; ulong Base; } GDTR, *PGDTR; #pragma pack() static ushort * pVideoBeg = (ushort *)0xb8000; static ushort * pVideoEnd = (ushort *)0xb8fa0; static ushort * pCursor; static ushort wColor; static byte * pTarget = (byte *) 0x7c00; static char szHexDigits[] = "0123456789abcdef"; extern ulong BlMmGetCr3(void); extern void BlMmSetCr3(ulong Value); extern void BlMmGetGdtr(PGDTR Gdtr); extern void BlMmSetGdtr(PGDTR Gdtr); extern ulong BlMmGetRsp(void); // // Include: byte lomem_data[]; // #include void PrintChar(char c) { if (c == '\n') { while (((pCursor - pVideoBeg) % 80) != 0) { *pCursor++ = wColor + ' '; } } else if (c == '\f') { while (pCursor > pVideoBeg) { *--pCursor = wColor + ' '; } } else { *pCursor++ = wColor + c; } } void PrintString(const char * psz) { for (; *psz; psz++) { PrintChar(*psz); } } void PrintHexValueSub(ulong v, int digits) { int i; for (i = 4 * (digits - 1); i >= 0; i -= 4) { *pCursor++ = wColor + szHexDigits[(v >> i) & 0xf]; } } void PrintHex32(uint v) { PrintHexValueSub((ulong)v, 8); } void PrintHexValue(ulong v) { PrintHexValueSub(v, 16); } void PrintHexDigit(byte v) { *pCursor++ = wColor + szHexDigits[(v >> 4) & 0xf]; *pCursor++ = wColor + szHexDigits[v & 0xf]; } void PrintDump(byte * data, int size, int pad) { for (; size > 0; size--, pad--) { PrintHexDigit(*data++); } for (; pad > 0; pad--) { PrintString(" "); } } void PrintChars(byte * data, int size, int pad) { for (; size > 0; size--, pad--) { byte b = *data++; if (b < ' ' || b > 127) { PrintChar('.'); } else { PrintChar((char)b); } } for (; pad > 0; pad--) { PrintString(" "); } } int FindEntry(const byte *data, int size) { const byte * walk = data; for (; size > 0; size--, walk++) { if (walk[0] == 'S' && walk[1] == 'I' && walk[2] == 'N' && walk[3] == 'G' && walk[4] == 'L' && walk[5] == 'R' && walk[6] == 'B' && walk[7] == 0x00 && walk[8] == 0xf8 && walk[9] == 0xf9 && walk[10] == 0xfa && walk[11] == 0xfb && walk[12] == 0xfc && walk[13] == 0xfd && walk[14] == 0xfe && walk[15] == 0xff) { return ((walk + 32) - data); } } return -1; } void CopyMemory(byte * target, const byte * data, int size) { PrintString("CopyMemory("); PrintHexValue((ulong)target); PrintString(","); PrintHexValue((ulong)data); PrintString(","); PrintHexValue((ulong)size); PrintString(")\n"); for (; size > 0; size--) { *target++ = *data++; } } void PrintSegment32(ulong seg) { PrintString(" "); PrintHexValueSub(seg >> 56, 2); PrintHexValueSub(seg >> 16, 6); PrintString(" "); PrintHexValueSub(seg >> 48, 1); PrintHexValueSub(seg >> 0, 4); PrintString(" "); PrintHexValueSub(seg >> 52, 1); PrintString(" "); PrintHexValueSub(seg >> 40, 2); } void PrintSegment64(ulong seg0, ulong seg1) { PrintHexValueSub(seg1 >> 0, 8); PrintHexValueSub(seg0 >> 56, 2); PrintHexValueSub(seg0 >> 16, 6); PrintString(" "); PrintHexValueSub(seg0 >> 48, 1); PrintHexValueSub(seg0 >> 0, 4); PrintString(" "); PrintHexValueSub(seg0 >> 52, 1); PrintString(" "); PrintHexValueSub(seg0 >> 40, 2); } void * FindModuleInfo(uint *pConfig, uint find, uint * pSize) { for (;;) { uint type = pConfig[0]; uint size = pConfig[1]; void *data = &pConfig[2]; if (type == 0) { *pSize = 0; return NULL; } if (type == find) { *pSize = size; return data; } size = (size + 8 + 7) & ~7u; pConfig = (uint *)(((byte *)pConfig) + size); } } void PrintModuleInfo(uint *pConfig) { PrintString("Module Info:\n"); for (;;) { uint type = pConfig[0]; uint size = pConfig[1]; void *data = &pConfig[2]; if (type == 0) { break; } PrintString(" "); PrintHex32((uint)pConfig); PrintString(":"); PrintHex32(type); PrintString("["); PrintHex32(size); PrintString("]:"); PrintDump((byte*)data, size < 16 ? size : 16, 16); PrintString(" "); PrintChars((byte*)data, size < 16 ? size : 16, 16); PrintString("\n"); size = (size + 8 + 7) & ~7u; pConfig = (uint *)(((byte *)pConfig) + size); } } void __fastcall main(uint *pConfig, uint * pUnknown) { int offset; void (*pStart)(void); byte * pbSmap; uint cbSmap; wColor = 0x4f00; pCursor = pVideoBeg; PrintString("Singularity Reloader " __DATE__ " " __TIME__ "\n"); offset = FindEntry(lomem_data, sizeof(lomem_data)); pStart = (void (*)(void))(pTarget + offset); PrintString("pConfig = "); PrintHexValue((ulong)pConfig); PrintString("\n"); PrintString("pUnknown = "); PrintHexValue((ulong)pUnknown); PrintString("\n"); PrintString(" "); PrintDump((byte*)pUnknown, 16, 16); PrintString(" "); PrintChars((byte*)pUnknown, 16, 16); PrintString("\n"); PrintString("pTarget = "); PrintHexValue((ulong)pTarget); PrintString(".."); PrintHexValue((ulong)(pTarget + sizeof(lomem_data))); PrintString("\n"); // PrintModuleInfo(pConfig); #if 0 PrintString("lomem = "); PrintHexValue((ulong)lomem_data); PrintString(".."); PrintHexValue((ulong)(lomem_data + sizeof(lomem_data))); PrintString("\n"); #endif #if 0 { ulong cr3; ulong *p; GDTR gdt; cr3 = BlMmGetCr3(); PrintString("cr3 = "); PrintHexValue((ulong)cr3); PrintString("\n"); p = (ulong *)cr3; PrintString("cr3.0 = "); PrintHexValue((ulong)p[0]); PrintString(" "); PrintHexValue((ulong)p[1]); PrintString(" "); PrintHexValue((ulong)p[2]); PrintString(" "); PrintHexValue((ulong)p[3]); PrintString("\n"); p = (ulong *)(p[0] & 0xfffffffffffff000); PrintString("cr3.0.0 = "); PrintHexValue((ulong)p[0]); PrintString(" "); PrintHexValue((ulong)p[1]); PrintString(" "); PrintHexValue((ulong)p[2]); PrintString(" "); PrintHexValue((ulong)p[3]); PrintString("\n"); p = (ulong *)(p[0] & 0xfffffffffffff000); PrintString("cr3.0.0.0 = "); PrintHexValue((ulong)p[0]); PrintString(" "); PrintHexValue((ulong)p[1]); PrintString(" "); PrintHexValue((ulong)p[2]); PrintString(" "); PrintHexValue((ulong)p[3]); PrintString("\n"); p = (ulong *)cr3; p = (ulong *)(p[0] & 0xfffffffffffff000); p = (ulong *)(p[3] & 0xfffffffffffff000); PrintString("cr3.0.3.0 = "); PrintHexValue((ulong)p[0]); PrintString(" "); PrintHexValue((ulong)p[1]); PrintString(" "); PrintHexValue((ulong)p[2]); PrintString(" "); PrintHexValue((ulong)p[3]); PrintString("\n"); BlMmGetGdtr(&gdt); #if 0 PrintString("gdt = "); PrintHexValue((ulong)gdt.Base); PrintString(".."); PrintHexValue((ulong)gdt.Limit); PrintString("\n"); #endif p = (ulong *)gdt.Base; PrintString("gdt.1 = "); PrintSegment32(p[1]); PrintString(" : "); PrintSegment64(p[1],p[2]); PrintString("\n"); PrintString("gdt.2 = "); PrintSegment32(p[2]); PrintString(" : "); PrintSegment64(p[2],p[3]); PrintString("\n"); PrintString("gdt.3 = "); PrintSegment32(p[3]); PrintString(" : "); PrintSegment64(p[3],p[4]); PrintString("\n"); PrintString("gdt.4 = "); PrintSegment32(p[4]); PrintString(" : "); PrintSegment64(p[4],p[5]); PrintString("\n"); PrintString("gdt.5 = "); PrintSegment32(p[5]); PrintString(" : "); PrintSegment64(p[5],p[6]); PrintString("\n"); PrintString("gdt.6 = "); PrintSegment32(p[6]); PrintString(" : "); PrintSegment64(p[6],p[7]); PrintString("\n"); PrintString("gdt.7 = "); PrintSegment32(p[7]); PrintString(" : "); PrintSegment64(p[7],p[8]); PrintString("\n"); PrintString("gdt.8 = "); PrintSegment32(p[8]); PrintString(" : "); PrintSegment64(p[8],p[9]); PrintString("\n"); PrintString("gdt.9 = "); PrintSegment32(p[9]); PrintString(" : "); PrintSegment64(p[9],p[10]); PrintString("\n"); PrintString("gdt.a = "); PrintSegment32(p[10]); PrintString(" : "); PrintSegment64(p[10],p[11]); PrintString("\n"); } #endif CopyMemory(pTarget, lomem_data, sizeof(lomem_data)); pbSmap = (byte *)FindModuleInfo(pConfig, 0x9001, &cbSmap); if (pbSmap != NULL) { byte * pnew = (byte *)0x1000; CopyMemory(pnew, pbSmap, cbSmap); pbSmap = pnew; } for (offset = 0; offset < cbSmap; offset += 20) { PrintString(" SMAP["); PrintHexDigit((byte)(offset / 20)); PrintString("] "); PrintHexValue(((ulong *)(pbSmap + offset + 0))[0]); PrintString(" x "); PrintHexValue(((ulong *)(pbSmap + offset + 8))[0]); PrintString(" "); PrintHex32(((uint *)(pbSmap + offset + 16))[0]); PrintString("\n"); } ((uint *)pStart)[-4] = 0x600000; ((uint *)pStart)[-3] = (uint)pbSmap; ((uint *)pStart)[-2] = cbSmap; PrintString("pbSmap = "); PrintHexValue((ulong)pbSmap); PrintString("\n"); PrintString("pTarget = "); PrintHexValue((ulong)pTarget); PrintString(" ["); PrintDump((byte *)pTarget, 16, 16); PrintString("]\n"); PrintString("pStart = "); PrintHexValue((ulong)(pStart)); PrintString(" ["); PrintDump((byte *)pStart, 16, 16); PrintString("]\n"); #if 0 { byte * pb = (byte *)0x600000; int bad = 0; int i; PrintString("Scanning:\n"); for (i = 0; i < 0x800000; i++) { if (pb[i] != 0xee) { PrintString(" "); PrintHexValue((ulong)i); PrintString(": "); PrintDump(pb, i, 16); PrintString("\n"); i += 16; bad++; if (bad > 20) { for (;;); } } } } #endif #if 0 PrintString("Test1\n"); { uint target = 0x500000; uint offset; for (offset = 1; offset < 0x10000000; offset <<= 1) { PrintString(" "); PrintHex32(target + offset); PrintString(" : "); *((uint *)(target + offset)) = (0xff000000 | offset); PrintHex32(*((uint *)(target + offset))); PrintString("\n"); } } PrintString("Test2\n"); for(;;); #endif pStart(); PrintString("Halt.\n"); for (;;); // pStart(); }