
ओपन सोर्स Windows x64 PE पैकर और क्रिप्टर। यह कस्टम वर्चुअल मशीन का उपयोग करके निष्पादन योग्य फ़ाइलों (executables) को संपीड़ित और एन्क्रिप्ट करता है, तथा उन्हें एक स्व-निष्कर्षण स्टब (self-extracting stub) में बदल देता है।
TinyLoad x64 एक्ज़ीक्यूटेबल के लिए एक PE क्रिप्टर/पैकर है। यह एक इनपुट exe को अलग-अलग सुरक्षा परतों के साथ पैक करता है ताकि इसे रिवर्स इंजीनियर न किया जा सके। यह सिर्फ एक .cpp फ़ाइल है और इसकी कोई बाहरी निर्भरता नहीं है।
TinyLoad आपके पेलोड को अपनी एक कॉपी के साथ जोड़ देता है। जब पैक किया गया exe चलता है तो यह पेलोड को निकालता है, उसे डिक्रिप्ट करता है, और उसे सीधे मेमोरी में चलाता है — बिना कभी मूल फ़ाइल को डिस्क पर लिखे। हर बार जब आप कुछ पैक करते हैं, VM ऑपकोड बेतरतीब ढंग से बदल दिए जाते हैं और 4 अलग-अलग कुंजी वाली सबटेबल्स में रखे जाते हैं, इसलिए कोई भी दो बिल्ड एक जैसे नहीं होते।
flowchart TD
start["pack(in, out, vm, comp, veh, noconsole)"] --> load["loadFile(in) → orig"]
load --> pe{"MZ + PE00 + Machine 0x8664 + NumberOfSections in 1..96?"}
pe -->|fail| err["printf error / return false"]
pe -->|ok| init["pay = orig flags = 0"]
init --> cdec{"--c ?"}
cdec -->|yes| lz["flags |= 1<br/>lzPack: WINDOW=0xFFFF MAXCHAIN=4096<br/>MAXMATCH=258 MINMATCH=3 HSIZE=65536<br/>hash4 = FNV-ish fold * 0x1000193<br/>lazy lookahead la = 1,2<br/>out = uint32le origSz + 8-token flag bytes<br/>match → varint dist, varint len-3"]
cdec -->|no| vmq
lz --> vmq{"--vm ?"}
vmq -->|yes| scatter["flags |= 2<br/>Fisher-Yates 32 slots, scatter NUM_OPS=28<br/>into subtables 4x8, unused stay 0xFF<br/>opmap_enc op = tbl shl 6 OR idx"]
scatter --> canary["canary corridor n=8, skip first 0x400 of pay<br/>canExp c = pay at off XOR prev"]
canary --> mkvm["makeVmProgram opmap_enc, key1, key2, canary<br/>key1,key2 ← mt19937_64 TickCount64 XOR QPC<br/>opaque predicates + stream loop + canary mask"]
mkvm --> venc["vmEncryptPayload 192-bit state<br/>k3 = 0x9E3779B97F4A7C15<br/>ks = uint8((k1 XOR k2) + k3)<br/>b = NOT(b XOR ks)<br/>k1 = rotl64(k1,11) XOR k2<br/>k2 = rotr64(k2,19) + k1 + k3<br/>k3 = k3 * phi XOR k1"]
vmq -->|no| vehq
venc --> vehq{"--veh ?"}
vehq -->|yes| vflag["flags |= FLAG_VEH 4"]
vehq -->|no| stub
vflag --> stub["stub = loadFile GetModuleFileNameA self<br/>saveFile out, stub as host image"]
stub --> skey["stubKey = 0x9E3779B97F4A7C15<br/>for i in 0x1000 .. min n, 0x2000:<br/>stubKey = (stubKey XOR stub i) * phi"]
skey --> disp["prime vmRun dispKey=0 → fill g_off<br/>dispKey ← rng<br/>encOff j = uint64(g_off j) XOR dispKey"]
disp --> tail["Tail: sig TINYLD60, origSz, packSz, flags,<br/>dispOff x28, subtables 4x8, vmCodeSz,<br/>dispKey, canary*, chunk*,<br/>payHash = SHA-256 orig first 8B"]
tail --> hide["sig i XOR= stubKey shr 8i<br/>xorOpmap FNV-1a 0x811C9DC5 / 0x01000193<br/>feeds origSz, packSz, vmCodeSz + first 32B<br/>of vmCode and pay, per-table<br/>flags |= FLAG_CHUNK 8"]
hide --> tenc["XOR-encode Tail fields with stubKey slices<br/>vmCode vi XOR= stubKey shr ((vi*3) and 63)"]
tenc --> ovl["payload = vmCode || pay<br/>interleave: insert 0x00 after every 3 bytes"]
ovl --> chunks["split into 4 chunks, shuffle physical order<br/>Tail placeholder TAIL_SERIALIZED_SZ = 419<br/>before each chunk: 128..640 RNG junk"]
chunks --> tea["xxteaEncrypt bytes after Tail<br/>DELTA=0x9E3779B9 rounds=6+52/n<br/>remainder XOR pxKey0 xor pxKey1 xor pxKey2 xor pxKey3<br/>patch k i XOR FEEDF00D / CAFEBABE /<br/>DEADBEEF / 8BADF00D into _pxBlock<br/>between C0DE1337 and B007DEAD"]
tea --> ser["XOR chunkOff / chunkSz / chunkOrder / chunkCnt<br/>serializeTail: 16 TLV records id + u16le sz + bytes<br/>Fisher-Yates order, LCG 1103515245+12345<br/>seed = stubKey XOR filesize<br/>append DWORD LE: tailOff XOR stubKey low 32"]
ser --> fin{"--noconsole ?"}
fin -->|yes| gui["OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI"]
fin -->|no| scr
gui --> scr["scrambleSections: cycle names<br/>.text .data .rdata .bss .idata"]
scr --> done["saveFile out, result"]releases से पहले से कंपाइल किया हुआ बाइनरी लें या इसे खुद बनाएं।
आपको MinGW (g++) चाहिए। बस यह चलाएं:
g++ -o TinyLoad.exe TinyLoad.cpp -static -O2 -s
या build.bat का उपयोग करें।
TinyLoad.exe --i <input> [--o <output>] [--vm] [--c] [--veh]
आपको --vm, --c, या --veh में से कम से कम 1 की आवश्यकता है।
हैश चेन मैचिंग और 64KB स्लाइडिंग विंडो के साथ कस्टम LZ77 कम्प्रेशन। कम्प्रेशन पहले चलता है, फिर VM एन्क्रिप्शन उसके ऊपर लगता है ताकि कंप्रेस्ड डेटा में मौजूद कोई भी पैटर्न भी छिप जाए।
कस्टम 28 ऑपकोड वर्चुअल मशीन जो स्टब के अंदर चलती है। ऑपकोड बेतरतीब ढंग से 4 सबटेबल्स में 8-8 के समूह में रखे जाते हैं और हर सबटेबल को पेलोड डेटा से प्राप्त अलग-अलग कुंजी से XOR एन्क्रिप्ट किया जाता है। 1 सबटेबल को क्रैक करने पर 28 में से अधिकतम 8 ऑपकोड ही पता चलते हैं। सिफर स्वयं एक 128-बिट स्ट्रीम सिफर है जो rotl और rotr कुंजी मिक्सिंग का उपयोग करता है और पूरी तरह से VM इंटरप्रेटर के अंदर चलता है। पेलोड को XXTEA का उपयोग करके एन्क्रिप्ट किया जाता है।
--veh सक्षम होने पर, सभी PE सेक्शन पेज PAGE_NOACCESS के रूप में मैप हो जाते हैं। जब प्रोग्राम किसी पेज को एक्सेस करने की कोशिश करता है तो यह एक एक्सेप्शन ट्रिगर करता है, एक वेक्टर्ड एक्सेप्शन हैंडलर सिर्फ उस 1 पेज को डिक्रिप्ट करता है और सही प्रोटेक्शन सेट करता है। एक वॉचडॉग थ्रेड बैकग्राउंड में चलता है और किसी भी पेज को फिर से एन्क्रिप्ट करता है जिसे 200ms में एक्सेस नहीं किया गया है। किसी भी समय आपके प्रोग्राम का अधिकांश हिस्सा मेमोरी में एन्क्रिप्टेड रहता है, इसलिए मेमोरी डंप केवल वही कैप्चर करते हैं जो हाल ही में एक्सेस किया गया था।
4 सबसे महत्वपूर्ण APIs (GetModuleHandleA, GetProcAddress, ExitProcess, VirtualAlloc) को स्टब के अंदर रैपर फ़ंक्शन के माध्यम से रीडायरेक्ट किया जाता है। पेलोड लोड होने के बाद पूरी इम्पोर्ट डायरेक्ट्री को शून्य कर दिया जाता है ताकि मेमोरी डंप इम्पोर्ट टेबल का पुनर्निर्माण न कर सकें।
MIT
| फ़्लैग | यह क्या करता है |
|---|
--i <file> | पैक करने के लिए इनपुट exe |
--o <file> | आउटपुट पथ (डिफ़ॉल्ट: input_packed.exe) |
--vm | VM एन्क्रिप्शन |
--c | LZ77 कम्प्रेशन |
--veh | VEH पेज फॉल्ट डिक्रिप्शन |
--noconsole | GUI सबसिस्टम |