Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
Mergen — LLVM IR और पार्सिंग असेंबली के उपयोग के साथ ऑप्टिमाइज़ेशन के माध्यम से डीओबफस्केशन। | Kitploit
उपकरण/GitHubGitHub/nac-l/mergen
स्थैतिक विश्लेषणगतिशील विश्लेषण (सैंडबॉक्सिंग)रिवर्स इंजीनियरिंगबाइनरी विश्लेषणबाइनरी शोषण
GitHubnac-l/mergen

Mergen

LLVM IR और पार्सिंग असेंबली के उपयोग के साथ ऑप्टिमाइज़ेशन के माध्यम से डीओबफस्केशन।

रिपॉजिटरी देखें
878943 महीने पहलेKitploit द्वारा समीक्षित

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

परियोजना अवलोकन:

Mergen एक उपकरण है जिसे असेंबली कोड को LLVM मध्यवर्ती प्रतिनिधित्व (IR) में बदलने के लिए इंजीनियर किया गया है। यह उपकरण इसके लिए डिज़ाइन किया गया है:

  • अस्पष्ट बाइनरी कोड का डीऑबफस्केशन या डीवर्चुअलाइज़ेशन
  • रिवर्स इंजीनियरिंग प्रक्रिया को बढ़ाना, इसे और अधिक कुशल और प्रभावी बनाना, विशेष रूप से जटिल सॉफ्टवेयर सिस्टम के लिए।

बनाने और चलाने के लिए मार्गदर्शिका

प्रोजेक्ट बनाने और चलाने के लिए, docs/BUILDING.md देखें।

रीराइट बेसलाइन गेट

रीराइट कार्य को बेसलाइन रिग्रेशन गेट को हरा रखना चाहिए। गेट केंद्रित PE नमूने बनाता है, lifter चलाता है, और लिफ्ट किए गए IR आउटपुट को सत्यापित करता है।

  • कार्यप्रवाह दस्तावेज़: docs/REWRITE_BASELINE.md
  • एक-कमांड गेट: scripts\\rewrite\\run.cmd

मुख्य उद्देश्य:

  • डीऑबफस्केशन

  • डीवर्चुअलाइज़ेशन

  • अनुकूलन

यह कैसे काम करता है?

हम लक्ष्य को प्रतीकात्मक रूप से निष्पादित (या प्रतीकात्मक रूप से लिफ्ट) करते हैं, यहाँ विचार व्यक्तिगत निर्देशों को लिफ्ट करने का नहीं है, बल्कि पूरे फ़ंक्शन को लिफ्ट करने का है। हम उम्मीद नहीं करते कि एक निर्देश या एक मूल ब्लॉक हर बार समान व्यवहार करे, बल्कि उन्हें ऐसे मानें जैसे वे हर बार अलग-अलग उद्देश्यों के लिए हो सकते हैं और होते हैं। हम उत्पन्न IR को यथासंभव सरल और अनुकूलनीय रखने का प्रयास करते हैं। हमारी आवश्यकताएँ एक सामान्य कंपाइलर से भिन्न होती हैं। हम नियंत्रण प्रवाह का मूल्यांकन करने के लिए विश्लेषण का उपयोग करते हैं। हम अपने सभी विश्लेषणों के लिए LLVM पर निर्भर नहीं रह सकते, क्योंकि वे विभिन्न लक्ष्यों के लिए बनाए गए हैं और हमारे उपयोग-मामले के लिए अनुकूलित नहीं हो सकते।

image

उदाहरण

यह व्यावहारिक उदाहरण है जो दर्शाता है कि Mergen वर्चुअलाइज़्ड प्रोग्रामों के विरुद्ध कैसे हल करता है।

  1. VMProtect
  2. Branches/Jumptables
  3. Themida 3.1.6.0 LION64 (Red)

उदाहरण #1 (VMProtect)

यह हमारा लक्ष्य प्रोग्राम है

root@kitploit:~
struct test {
    int a;
    int b;
    int c;
};

int maths(test a, int b, int c) {
        return a.a  + b - c;
}

image

image

VMProtect सेटिंग्स, सब कुछ बंद है, हम फ़ंक्शन को अल्ट्रा सेटिंग पर वर्चुअलाइज़ करते हैं। (परीक्षित संस्करण 3.4.0-3.6.0 3.8.1)

image

image

यहाँ, हम mergen चलाते हैं। पहला तर्क फ़ाइल का नाम है और दूसरा तर्क फ़ंक्शन का पता है। देखें कि इसे चलाना कितना सरल है। और हम आउटपुट को संकलित कर सकते हैं ताकि हम अपने पसंदीदा डीकंपाइलर का उपयोग करके इसका अन्वेषण कर सकें।

image

root@kitploit:~
; ModuleID = 'my_lifting_module'
source_filename = "my_lifting_module"

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
define i64 @main(i64 %rax, i64 %rcx, i64 %rdx, i64 %rbx, i64 %0, i64 %rbp, i64 %rsi, i64 %rdi, i64 %r8, i64 %r9, i64 %r10, i64 %r11, i64 %r12, i64 %r13, i64 %r14, i64 %r15, ptr nocapture readonly %memory) local_unnamed_addr #0 {
entry:
  %stackmemory = alloca i128, i128 13758960, align 8
  %1 = trunc i64 %r8 to i32
  %2 = trunc i64 %rdx to i32
  %GEPLoadxd-5369456437- = getelementptr i8, ptr %memory, i64 %rcx
  %3 = load i32, ptr %GEPLoadxd-5369456437-, align 4
  %adc-temp-5370242400- = sub i32 %2, %1
  %realnot-5369532059- = add i32 %adc-temp-5370242400-, %3
  %stackmemory10243.sroa.55.1375304.insert.ext10255 = zext i32 %realnot-5369532059- to i64
  ret i64 %stackmemory10243.sroa.55.1375304.insert.ext10255
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }

संकलन के बाद:

image

image

अब आप देख सकते हैं कि रजिस्टर थोड़े गड़बड़ हैं। ऐसा इसलिए है क्योंकि हम कॉलिंग कन्वेंशन का पालन नहीं करते, यदि हम कॉलिंग कन्वेंशन का पालन करते, तो फ़ंक्शन हस्ताक्षर इस तरह दिखता:

root@kitploit:~
define i64 @main(i64 %rcx, i64 %rdx, i64 %rdx, i64 %r8, i64 %r9 ...)

इसलिए, हम फ़ंक्शन हस्ताक्षर को सामान्य दिखने के लिए समायोजित करते हैं। यदि आपके इस भाग के बारे में और प्रश्न हैं, तो मेरा सुझाव है कि आप calling conventions और ABI पर शोध करें।

उदाहरण #2 (शाखाएँ/जम्पटेबल्स)

तो, मान लें कि हमारे पास यह कोड है। VM नीचे दिए गए कोड को लेकर इसे एक अप्रत्यक्ष जंप में बदल देंगे, यह रिवर्सर के लिए थोड़ा अधिक असुविधाजनक है।

root@kitploit:~
int maths(int a, int b, int c) {
    if (a > b)
        return a + b + c;
    else
        return a - b - c;
}
root@kitploit:~
next_handler = xxx;
if ( a-b > 0 )
  next_handler = yyy;
jump next_handler;

हम हमेशा मानों का विश्लेषण करने और उन पर नज़र रखने का प्रयास करते हैं। यह हमें नियंत्रण प्रवाह को समझने की अनुमति देता है। जम्पटेबल-जैसी शाखाओं के लिए अनुकूलित आउटपुट एक सरल होगा

root@kitploit:~
define i64 @main(i64 %rax, i64 %rcx, i64 %rdx, i64 %rbx, i64 %rsp, i64 %rbp, i64 %rsi, i64 %rdi, i64 %r8, i64 %r9, i64 %r10, i64 %r11, i64 %r12, i64 %r13, i64 %r14, i64 %r15, ptr nocapture readnone %TEB, ptr nocapture readnone %memory) local_unnamed_addr #0 {
fake_ret:
  %0 = lshr i64 %rcx, 62
  %common.ret.op = and i64 %0, 2
  ret i64 %common.ret.op
}

अनुकूलित आउटपुट। (पठनीयता के लिए DCE किया गया)

root@kitploit:~
source_filename = "my_lifting_module"

define i64 @main(i64 %rax, i64 %rcx, i64 %rdx, i64 %rbx, i64 %rsp, i64 %rbp, i64 %rsi, i64 %rdi, i64 %r8, i64 %r9, i64 %r10, i64 %r11, i64 %r12, i64 %r13, i64 %r14, i64 %r15, ptr %TEB, ptr %memory) {
  %lsb = and i64 %rcx, 255
  %pf1 = mul i64 %lsb, 72340172838076673
  %pf2 = and i64 %pf1, -9205322385119247871
  %pf3 = urem i64 %pf2, 511
  %pf4 = and i64 %pf3, 1
  %pf5 = icmp eq i64 0, %pf4
  %0 = zext i1 %pf5 to i64
  %createrflag2 = shl i64 %0, 2
  %creatingrflag = or i64 2, %createrflag2
  %zeroflag = icmp eq i64 %rcx, 0
  %1 = zext i1 %zeroflag to i64
  %createrflag21 = shl i64 %1, 6
  %creatingrflag2 = or i64 %creatingrflag, %createrflag21
  %signflag = icmp slt i64 %rcx, 0
  %2 = zext i1 %signflag to i64
  %createrflag23 = shl i64 %2, 7
  %creatingrflag4 = or i64 %creatingrflag2, %createrflag23
  %GEPSTORE-5368713221- = getelementptr i8, ptr %memory, i64 1376032
  store i64 %creatingrflag4, ptr %GEPSTORE-5368713221-, align 4
  %realand-5368713229- = and i64 %creatingrflag4, 128
  %shr-lshr-5368713233- = lshr i64 %realand-5368713229-, 7
  %3 = mul i64 %shr-lshr-5368713233-, 4
  %bvalue_indexvalue = add i64 5368713249, %3
  %4 = icmp eq i64 %bvalue_indexvalue, 5368713253
  %lolb- = select i1 %4, i64 5368713264, i64 5368713257
  %GEPSTORE-5368713248- = getelementptr i8, ptr %memory, i64 1376032
  store i64 %lolb-, ptr %GEPSTORE-5368713248-, align 4
  br i1 %4, label %real_ret, label %real_ret41

real_ret:                                         ; preds = %fake_ret
  %inc-5368713273- = add i64 %shr-lshr-5368713233-, 1
  ret i64 %inc-5368713273-

real_ret41:                                       ; preds = %fake_ret
  ret i64 %shr-lshr-5368713233-
}

इस भाग पर ध्यान दें

root@kitploit:~
  %realand-5368713229- = and i64 %creatingrflag4, 128
  %shr-lshr-5368713233- = lshr i64 %realand-5368713229-, 7

हम फ़्लैग प्राप्त करते हैं, फिर हम 7वाँ बिट प्राप्त करते हैं जो साइन फ़्लैग है, फिर हम एक पता गणना करने के लिए साइन फ़्लैग का उपयोग करते हैं। विश्लेषण के माध्यम से, हम निर्धारित करते हैं कि पता दो मानों में से एक हो सकता है, 5368713257 या 5368713264, फिर हम इसे एक तुलना में बदल देते हैं। यदि पता 5368713257 है, तो एक शाखा लें, यदि दूसरा, तो दूसरी लें। ऐसा करते समय, शर्त को उपयुक्त मान के रूप में चिह्नित करना भी महत्वपूर्ण है क्योंकि बाद में, हमें उसी सटीक मान के साथ एक और जंप की गणना करने की आवश्यकता हो सकती है।

भले ही हम अप्रत्यक्ष जंप को हल करते हैं, 2 से अधिक संभावित स्थानों वाले जंप समर्थित नहीं हैं। ऐसा इसलिए है क्योंकि उनके लिए विश्लेषण अभी तक लागू नहीं किया गया है। यह हमें vm-शैली की शाखाओं को हल करने की अनुमति देता है, लेकिन वास्तविक जीवन की जम्पटेबल्स के साथ समस्या है।

उदाहरण #3 (Themida 3.1.6.0 LION64 (Red))

हमारा लक्ष्य प्रोग्राम:

image

Themida सेटिंग्स (हमें फिलहाल केवल vms की परवाह है):

image

image

image

VM के बाद:

image

Mergen चलाना:

image

आउटपुट कोड: यहाँ क्लिक करें तो, हमारा परिणाम vmp द्वारा सुरक्षित बाइनरी को लिफ्ट करने जितना सफल क्यों नहीं है?

Themida सक्रिय रूप से .themida अनुभाग पर लिखता है। स्टैक के विपरीत, हम इन लेखों को नज़रअंदाज़ नहीं कर सकते, क्योंकि इन मानों को बाद में अन्य चीज़ों द्वारा पढ़ा जा सकता है।

लेकिन, हमारे पास इसका एक अस्थायी समाधान है। .themida अनुभाग में सभी स्टोर हटा दें। चूंकि हमारा प्रोग्राम मेमोरी में नहीं लिखता, मैंने सभी स्टोर को टिप्पणी के रूप में डाल दिया। अब हम इसके साथ बचे हैं:

root@kitploit:~
source_filename = "my_lifting_module"

define i64 @main(i64 %rax, i64 %rcx, i64 %rdx, i64 %rbx, i64 %rsp, i64 %rbp, i64 %rsi, i64 %rdi, i64 %r8, i64 %r9, i64 %r10, i64 %r11, i64 %r12, i64 %r13, i64 %r14, i64 %r15, ptr writeonly %memory) local_unnamed_addr #0 {
  %trunc = trunc i64 %r8 to i32
  %trunc1 = trunc i64 %rdx to i32
  %trunc2 = trunc i64 %rcx to i32
  %realadd-5369771371- = add i32 %trunc1, %trunc2
  %realadd-5369582686- = add i32 %realadd-5369771371-, %trunc
  %trunc457139 = zext i32 %realadd-5369582686- to i64
  ret i64 %trunc457139
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }

तकनीकी चुनौतियाँ

  • लूप्स
  • स्व-संशोधित कोड (विशेष रूप से सशर्त संशोधन के साथ)
  • एक ऐसे ब्रह्मांड में होना जहाँ "आउटलाइनिंग" और "अनरोलिंग" पास मौजूद नहीं हैं।

संपर्क में आना

विचारों का आदान-प्रदान करने या सामान्य रूप से बातचीत करने के लिए हमारे Mergen Discord सर्वर से जुड़ें।

टूल डाउनलोड करें