Обфускация

Статус
В этой теме нельзя размещать новые ответы.

gamblemode

Новичок
Автор темы
4
0
Здравствуйте. Решил немного копнуть в сторону обфускации исходного кода. Знаний хватило, чтобы получилось это:
Код:
#9#S1F:=Object(#9#F1("6761797365726365746b657930"), #9#F1("6a756e6b6a756e6b6a69756e6b2323"), #9#F1("6761797365726365746b657931"), #9#F1("66616b656a756e6b636f64656c32321f")),#9#SF1:=Object(#9#F1("6761797365726365746b657930"), #9#F1("66616b6566616c6b6566616b654242421"), #9#F1("6761797365726365746b657931"), #9#F1("676164666b6e66616b65636f64654242b") , #9#F1("6761797365726365746b657932"), #9#F1("6c756c69747366616b6542421bf34")),#9$#F1:=Object(#9#F1("6761797365726365746b657930"), #9#F1("4d794265737450617373776f7264"), #9#F1("6761797365726365746b657931"), #9#F1("484c5a755958667271765a43554278397161483257413d3d"), #9#F1("6761797365726365746b657932"), #9#F1("6a54436d3138696937544c487a316b356462765878773d3d")),#9#SF1[#9#F1("6761797365726365746b657930")]:=#9$#F1[#9#F1("6761797365726365746b657930")],#9#SF1[#9#F1("6761797365726365746b657931")]:=#9$#F1[#9#F1("6761797365726365746b657931")],#9#SF1[#9#F1("6761797365726365746b657932")]:=#9$#F1[#9#F1("6761797365726365746b657932")],#9#S1F[#9#F1("6761797365726365746b657930")]:=S.F(#9#SF1[#9#F1("6761797365726365746b657931")], #9#SF1[#9#F1("6761797365726365746b657930")], #9#F1(323536)),#9#S1F[#9#F1("6761797365726365746b657931")]:=S.F(#9#SF1[#9#F1("6761797365726365746b657932")], #9#SF1[#9#F1("6761797365726365746b657930")], #9#F1(323536))
MsgBox % (#9#S1F[#9#F1("6761797365726365746b657930")]#9#S1F[#9#F1("6761797365726365746b657931")])

#9#F1(#2#F){
    While (#3#F := SubStr(#2#F, A_Index*2-1, 2)) != ""
        #5#F .= Chr("0x" #3#F) 
    Return #5#F
}

Class S
{
    6361797325422365742(string, password, alg)
    {
        len := this.StrPutVar(string, str_buf, 0, "UTF-8")
        this.Crypt(str_buf, len, password, alg, 1)
        return this.b64Encode(str_buf, len)
    }
    F(string, password, alg)
    {
        len := this.b64Decode(string, encr_Buf)
        sLen := this.Crypt(encr_Buf, len, password, alg, 0)
        sLen /= 2
        return StrGet(&encr_Buf, sLen, "UTF-8")
    }
   
    Crypt(ByRef encr_Buf, ByRef Buf_Len, password, ALG_ID, CryptMode := 1)
    {
        ; WinCrypt.h
        static MS_ENH_RSA_AES_PROV := "Microsoft Enhanced RSA and AES Cryptographic Provider"
        static PROV_RSA_AES        := 24
        static CRYPT_VERIFYCONTEXT := 0xF0000000
        static CALG_SHA1           := 0x00008004
        static CALG_SHA_256        := 0x0000800c
        static CALG_SHA_384        := 0x0000800d
        static CALG_SHA_512        := 0x0000800e
        static CALG_AES_128        := 0x0000660e ; KEY_LENGHT := 0x80  ; (128)
        static CALG_AES_192        := 0x0000660f ; KEY_LENGHT := 0xC0  ; (192)
        static CALG_AES_256        := 0x00006610 ; KEY_LENGHT := 0x100 ; (256)
        static KP_BLOCKLEN         := 8
       
        if !(DllCall("advapi32.dll\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "Uint", PROV_RSA_AES, "UInt", CRYPT_VERIFYCONTEXT))
            MsgBox % "*CryptAcquireContext (" DllCall("kernel32.dll\GetLastError") ")"
       
        if !(DllCall("advapi32.dll\CryptCreateHash", "Ptr", hProv, "Uint", CALG_SHA1, "Ptr", 0, "Uint", 0, "Ptr*", hHash))
            MsgBox % "*CryptCreateHash (" DllCall("kernel32.dll\GetLastError") ")"
       
        passLen := this.StrPutVar(password, passBuf, 0, "UTF-8")
        if !(DllCall("advapi32.dll\CryptHashData", "Ptr", hHash, "Ptr", &passBuf, "Uint", passLen, "Uint", 0))
            MsgBox % "*CryptHashData (" DllCall("kernel32.dll\GetLastError") ")"
       
        if !(DllCall("advapi32.dll\CryptDeriveKey", "Ptr", hProv, "Uint", CALG_AES_%ALG_ID%, "Ptr", hHash, "Uint", (ALG_ID << 0x10), "Ptr*", hKey)) ; KEY_LENGHT << 0x10
            MsgBox % "*CryptDeriveKey (" DllCall("kernel32.dll\GetLastError") ")"
       
        if !(DllCall("advapi32.dll\CryptGetKeyParam", "Ptr", hKey, "Uint", KP_BLOCKLEN, "Uint*", BlockLen, "Uint*", 4, "Uint", 0))
            MsgBox % "*CryptGetKeyParam (" DllCall("kernel32.dll\GetLastError") ")"
        BlockLen /= 8
       
        if (CryptMode)
            DllCall("advapi32.dll\CryptEncrypt", "Ptr", hKey, "Ptr", 0, "Uint", 1, "Uint", 0, "Ptr", &encr_Buf, "Uint*", Buf_Len, "Uint", Buf_Len + BlockLen)
        else
            DllCall("advapi32.dll\CryptDecrypt", "Ptr", hKey, "Ptr", 0, "Uint", 1, "Uint", 0, "Ptr", &encr_Buf, "Uint*", Buf_Len)
       
        DllCall("advapi32.dll\CryptDestroyKey", "Ptr", hKey)
        DllCall("advapi32.dll\CryptDestroyHash", "Ptr", hHash)
        DllCall("advapi32.dll\CryptReleaseContext", "Ptr", hProv, "UInt", 0)
        return Buf_Len
    }
   
    StrPutVar(string, ByRef var, addBufLen := 0, encoding := "UTF-8")
    {
        tlen := ((encoding = "UTF-8" || encoding = "CP1200") ? 2 : 1)
        str_len := StrPut(string, encoding) * tlen
        VarSetCapacity(var, str_len + addBufLen, 0)
        StrPut(string, &var, encoding)
        return str_len - tlen
    }
   
    b64Encode(ByRef VarIn, SizeIn)
    {
        static CRYPT_STRING_BASE64 := 0x00000001
        static CRYPT_STRING_NOCRLF := 0x40000000
        DllCall("crypt32.dll\CryptBinaryToStringA", "Ptr", &VarIn, "UInt", SizeIn, "Uint", (CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF), "Ptr", 0, "UInt*", SizeOut)
        VarSetCapacity(VarOut, SizeOut, 0)
        DllCall("crypt32.dll\CryptBinaryToStringA", "Ptr", &VarIn, "UInt", SizeIn, "Uint", (CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF), "Ptr", &VarOut, "UInt*", SizeOut)
        return StrGet(&VarOut, SizeOut, "CP0")
    }
    b64Decode(ByRef VarIn, ByRef VarOut)
    {
        static CRYPT_STRING_BASE64 := 0x00000001
        static CryptStringToBinary := "CryptStringToBinary" (A_IsUnicode ? "W" : "A")
        DllCall("crypt32.dll\" CryptStringToBinary, "Ptr", &VarIn, "UInt", 0, "Uint", CRYPT_STRING_BASE64, "Ptr", 0, "UInt*", SizeOut, "Ptr", 0, "Ptr", 0)
        VarSetCapacity(VarOut, SizeOut, 0)
        DllCall("crypt32.dll\" CryptStringToBinary, "Ptr", &VarIn, "UInt", 0, "Uint", CRYPT_STRING_BASE64, "Ptr", &VarOut, "UInt*", SizeOut, "Ptr", 0, "Ptr", 0)
        return SizeOut
    }
}

Для усложнения анализа исходного кода используются: массивы с переменными и их содержанием, наборы похожих друг на друга символов, конвертация текста в хекс формат. Хотелось бы узнать, какие еще методы обфускации есть и совместимы ли они с AHK.
Также хотелось бы узнать, каким образом в данном коде спрятан вызов MsgBox. Спасибо.
Код:
#:="chr",#@:=(#_:=(##:=($:=(#$:=(_:=!"")<<_)<<_)<<_)<<_)<<#$,@:=#_<<_|#@,_#:=%#%(@|#$|_),__:=%#%(@|$|_),_@:=%#%(@|#_|#$|_),_$:=%#%(#@|_),@#:=%#%(@|_),@_:=%#%(@|##|$|#$|_),@@:=%#%(@|#_|$|_),@$:=%#%(@|#_|$),$#:=%#%(@|##|$|#$),$_:=%#%(@|#_|#$),$@:=%#%(@|##|#$|_),$$:=%#%(#@|##),###:=%#%(@|$),##_:=%#%(@|##|$),%###%%##_%%##_%%_#%%@#%%##_%%##_%(%#%(#@|##|$|_) __ _@ _@ @# %#%(@|$|#$|_) __ %#%(#@|#$) @_ %#%(@|#_|##),%#%(#@|@|##|_) $# @$,!_,_@ @$ $_,%#%(#@|##|#$) @@ _@ @$ " " _$ $# @_ @$ %#%(@|##) __ $_ " " _$ @@ @$ @_ $$ @_ @$ $@ __ %#%(@|#_|##|_) " " $$ @# _# $@ __ $_,_@ @$ $_,"",%#%(#@|@|##|_) $# @$,!_)
 
Последнее редактирование:

#Rin

Известный
Всефорумный модератор
1,214
1,043
Также хотелось бы узнать, каким образом в данном коде спрятан вызов MsgBox. Спасибо.
В самом начале одной переменной присваивается chr
А Chr возвращает символ по его коду.
А также тут есть битовые сдвиги.
 

gamblemode

Новичок
Автор темы
4
0
Пытался делать через Chr, но ахк же не может прочитать строку типа:
Код:
Chr(msgbox), % result
Что-то я не могу вкурить.
Добавил AES шифрование к примеру в шапке и немного припрятал ключ. Какие еще эффективные методы обфускации можно провернуть с AHK?
 

#Rin

Известный
Всефорумный модератор
1,214
1,043
Добавил AES шифрование к примеру в шапке и немного припрятал ключ.
Все криптования кода на уровне ахк кода бесполезны.
Пытался делать через Chr, но ахк же не может прочитать строку типа:
Chr(msgbox), % result
Chr возвращает символ по его коду.
Открой английскую документацию, там есть.
Какие еще эффективные методы обфускации можно провернуть с AHK?
Проще в движке че-то сделать.
 

gamblemode

Новичок
Автор темы
4
0
Все криптования кода на уровне ахк кода бесполезны.
Разве нельзя спрятать пароль в нескольких огромных массивах и поставить защиту от перебора + пару фич от ахк дебаггеров или это все равно не спасет? Пока копался в поисках истины, наткнулся на интересный обфускатор для JS , вот там действительно хорошие методы используются, например Self Defending, Control Flow Flattening, Dead Code Injection. Можете подсказать как работают эти фичи, примерный алгоритм работы?
 

#Rin

Известный
Всефорумный модератор
1,214
1,043
ахк дебаггеров
ahk дебаггеров, такие существуют?
поставить защиту от перебора
защита от перебора, и как ты это собрался реализовывать?
Разве нельзя спрятать пароль в нескольких огромных массивах
Зачем вообще человеку искать пароль, в любом случае первый закон крипторов: программа сама же себя раскриптует для работы.
Пока копался в поисках истины, наткнулся на интересный обфускатор для JS , вот там действительно хорошие методы используются, например Self Defending, Control Flow Flattening, Dead Code Injection. Можете подсказать как работают эти фичи, примерный алгоритм работы?
Темой обфускации не занимался, а так же для js есть деобфускаторы.
это все равно не спасет?
Самый лучший вариант, так это заменить все названия меток, переменных, функций, классов на рандомные названия, а все операции типо msgbox и т.п заменить также на рандом, эти рандом значения можно внести в ахк движок.
Исходники AHK_L (На котором все обычно пишут, сами того не зная): AutoHotkey/AutoHotkey(https://github.com/AutoHotkey/AutoHotkey)
Там много файлов, можешь изучить его и после составить свой набор команд, а так же включить построчную дешифровку (если сможешь фиксануть баг с которым ты столкнешься) ну или на крайняк полностью дешифровать после подгрузки., затирание памяти, защиту от отладчиков.
Тогда будет сложно вскрыть.
 

gamblemode

Новичок
Автор темы
4
0
ahk дебаггеров, такие существуют?
В AHK Studio и SciTE4ahk есть.
защита от перебора, и как ты это собрался реализовывать?
Можно просто очень сильно этому мешать, что даже и перебирать не захочется, суть же обфускации усложнить анализ кода.
Зачем вообще человеку искать пароль, в любом случае первый закон крипторов: программа сама же себя раскриптует для работы.
Чтобы восстановить обфусцированный код в исходное состояние. Ведь от обфусцированного кода нет толку. В памяти ведь код будет тоже обфусцированный или я чего-то не понимаю?
Самый лучший вариант, так это заменить все названия меток, переменных, функций, классов на рандомные названия, а все операции типо msgbox и т.п заменить также на рандом, эти рандом значения можно внести в ахк движок.
Исходники AHK_L (На котором все обычно пишут, сами того не зная): AutoHotkey/AutoHotkey(https://github.com/AutoHotkey/AutoHotkey)
Там много файлов, можешь изучить его и после составить свой набор команд, а так же включить построчную дешифровку (если сможешь фиксануть баг с которым ты столкнешься) ну или на крайняк полностью дешифровать после подгрузки., затирание памяти, защиту от отладчиков.
Тогда будет сложно вскрыть.
Увы, С++ не знаю, да и легче уж будет весь код на плюсах писать, если с движком-то разобраться смогу)
 
Статус
В этой теме нельзя размещать новые ответы.