HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby
   
 
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 08.02.2023, 20:07
colby57
Новичок
Регистрация: 13.02.2022
Сообщений: 12
С нами: 2236305

Репутация: 28
По умолчанию

Шалом, это мой первый тред на борде.

И решил немного доработать старый исходник, который проходится по функциям IAT (Import Address Table), проверяя их на опкоды джампа, и брейкпоинтов x32dbg (int3, int 0x3, ud2), Ordinal, кстати, он не проверяет, но можете допилить за меня

Такой приём будет очень полезен против новичков в вашем лоадере, которые любят ставить бряки куда попало без предварительного динамического анализа защиты

Для незнающих скажу, что если ваша функция накрыта виртуализацией кода, которая за собой как бонус будет вызывать функцию по своему функцию и и на этот адрес нет никаких других внешних вызовов в вашей программе, то этот чек пользователь спокойно пройдет, поскольку данной функции не будет в IAT.

Вот и сам исходник:

IATScan.hpp:





Код:
#pragma once
#include 
#include 
#include 
#include 
namespace
Engine
{
struct
S_CorruptedFunction
{
std
::
string m_cModuleName
;
std
::
string m_cFunctionName
;
std
::
uintptr_t m_pAddress
;
S_CorruptedFunction
(
std
::
string cModule
,
std
::
string cFunc
,
std
::
uintptr_t pAddress
)
:
m_cModuleName
(
std
::
move
(
cModule
)
)
,
m_cFunctionName
(
std
::
move
(
cFunc
)
)
,
m_pAddress
(
std
::
move
(
pAddress
)
)
{
}
}
;
inline
BYTE bInt3Breakpoint
=
0xCC
;
inline
BYTE bJumpOpcode
=
0xE9
;
inline
WORD wUd2Breakpoint
=
0x0B0F
;
inline
WORD wInt3Breakpoint
=
0x03CD
;
inline
std
::
vector

m_cCorruptedFunctions
{
}
;
void
OutputCorruptedFunctions
(
)
;
void
AddFunction
(
const
S_CorruptedFunction
&
cCorruptedFunctions
)
;
bool
IATScan
(
)
;
}


IATScan.cpp:





Код:
#include "IATScan.hpp"
void
Engine
::
OutputCorruptedFunctions
(
)
{
if
(
m_cCorruptedFunctions
.
empty
(
)
)
{
printf
(
"[~] No corrupted functions found!\n"
)
;
return
;
}
for
(
const
auto
&
Iterator
:
m_cCorruptedFunctions
)
printf
(
"[!] Module: %s\tFunction: %s\tAddress: 0x%p\n"
,
Iterator
.
m_cModuleName
.
c_str
(
)
,
Iterator
.
m_cFunctionName
.
c_str
(
)
,
Iterator
.
m_pAddress
)
;
}
void
Engine
::
AddFunction
(
const
S_CorruptedFunction
&
cCorruptedFunctions
)
{
m_cCorruptedFunctions
.
push_back
(
cCorruptedFunctions
)
;
}
bool
Engine
::
IATScan
(
)
{
LPVOID lpBaseAddress
=
(
LPVOID
)
GetModuleHandle
(
NULL
)
;
PIMAGE_DOS_HEADER pDosHeader
;
PIMAGE_NT_HEADERS pNtHeader
;
IMAGE_OPTIONAL_HEADER pOptionalHeader
;
IMAGE_DATA_DIRECTORY pImportDirectory
;
DWORD dwStartRVA
;
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor
;
pDosHeader
=
(
PIMAGE_DOS_HEADER
)
lpBaseAddress
;
if
(
pDosHeader
->
e_magic
!=
IMAGE_DOS_SIGNATURE
)
return
false
;
pNtHeader
=
(
PIMAGE_NT_HEADERS
)
(
(
DWORD_PTR
)
lpBaseAddress
+
pDosHeader
->
e_lfanew
)
;
if
(
pNtHeader
->
Signature
!=
IMAGE_NT_SIGNATURE
)
return
false
;
pOptionalHeader
=
pNtHeader
->
OptionalHeader
;
pImportDirectory
=
pOptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_IMPORT
]
;
dwStartRVA
=
pImportDirectory
.
VirtualAddress
;
pImportDescriptor
=
(
PIMAGE_IMPORT_DESCRIPTOR
)
(
(
DWORD_PTR
)
lpBaseAddress
+
dwStartRVA
)
;
if
(
pImportDescriptor
==
NULL
)
return
false
;
DWORD dwIndex
=
-
1
;
while
(
pImportDescriptor
[
++
dwIndex
]
.
Characteristics
!=
0
)
{
PIMAGE_THUNK_DATA pOriginalFirstThunk
;
PIMAGE_THUNK_DATA pFirstThunk
;
char
*
pDllName
=
(
char
*
)
(
(
DWORD_PTR
)
lpBaseAddress
+
pImportDescriptor
[
dwIndex
]
.
Name
)
;
HMODULE hModule
=
GetModuleHandleA
(
pDllName
)
;
pOriginalFirstThunk
=
(
PIMAGE_THUNK_DATA
)
(
(
DWORD_PTR
)
lpBaseAddress
+
pImportDescriptor
[
dwIndex
]
.
OriginalFirstThunk
)
;
pFirstThunk
=
(
PIMAGE_THUNK_DATA
)
(
(
DWORD_PTR
)
lpBaseAddress
+
pImportDescriptor
[
dwIndex
]
.
FirstThunk
)
;
if
(
pOriginalFirstThunk
==
nullptr
||
pFirstThunk
==
nullptr
)
return
false
;
while
(
pOriginalFirstThunk
->
u1
.
AddressOfData
)
{
if
(
!
(
pOriginalFirstThunk
->
u1
.
Ordinal
&
IMAGE_ORDINAL_FLAG
)
)
{
PIMAGE_IMPORT_BY_NAME pImageImport
=
(
PIMAGE_IMPORT_BY_NAME
)
(
(
LPBYTE
)
lpBaseAddress
+
pOriginalFirstThunk
->
u1
.
AddressOfData
)
;
auto
pFn
=
GetProcAddress
(
hModule
,
(
LPCSTR
)
pImageImport
->
Name
)
;
if
(
(
*
(
BYTE
*
)
pFn
==
bInt3Breakpoint
||
*
(
BYTE
*
)
pFn
==
bJumpOpcode
)
||
(
*
(
WORD
*
)
pFn
==
wUd2Breakpoint
||
*
(
WORD
*
)
pFn
==
wInt3Breakpoint
)
)
{
Engine
::
AddFunction
(
S_CorruptedFunction
(
std
::
string
(
pDllName
)
,
std
::
string
(
pImageImport
->
Name
)
,
(
std
::
uintptr_t
)
pFn
)
)
;
}
}
pFirstThunk
++
;
pOriginalFirstThunk
++
;
}
}
return
true
;
}


Пример его использования:

Entry.cpp:





Код:
#include "IATScan.hpp"
int
main
(
)
{
printf
(
"t.me/colby5engineering\n\n"
)
;
if
(
Engine
::
IATScan
(
)
==
true
)
Engine
::
OutputCorruptedFunctions
(
)
;
else
printf
(
"[-] Failed to scan iat :(\n"
)
;
std
::
cin
.
get
(
)
;
return
0
;
}


Результат использования функции:

1675872223136.pngcolby57 · 8 Фев 2023 в 19:07' data-fancybox="lb-post-1252723" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="https://www.blast.hk/attachments/189178/" style="cursor: pointer;" title="1675872223136.png">


Также забыл сказать, что функция _initialize_narrow_environment будет находится в списке, поскольку первый её байт - это 0xE9. Для неё можно спокойно сделать проверку.

Полный исходный код находится на гитхабе: https://github.com/colby57/IAT-Scanner

Всем пока!
 
Ответить с цитированием
 





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.