· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.VIROLOGY —› Не могу найти адреса API

Посл.отвђт Сообщенiе


Дата: Июл 3, 2004 14:41:56

Код:
include consts.inc
p386
model flat
locals __

.data


virstart:
db 'Choors Test',0
szTitle db "Choor test",0
szMessage db "Get Api Addr",10

virentry:
sub esp, virmemory
pusha

lea ebp, [esp+32]

call __seh_init
mov esp, [esp+8]
jmp __seh_error

__seh_init: push dword ptr fs:[0];
mov fs:[0], esp

call $+5
pop esi
sub esi, $-1-virstart

mov edi, ebp

mov ecx, virsize
rep movsb

lea eax, [ebp + in_new_addr-virstart]
call eax

__seh_error: pop dword ptr fs:[0]
pop eax

popa

db 0E9h
oldentry dd 0

jmp loader

; ---------------------------------------------------------------------- -----

in_new_addr:

call get_func_names
jc __exit
push eax
push esp
push 0
push ebp
lea eax, [ebp+newthread-virstart]
push eax
push 0
push 0
call x_CreateThread-virstart[ebp]
pop eax

__exit: retn

newthread: pusha
mov ebp, [esp+32+4]

call __seh_init
mov esp, [esp+8]
jmp __seh_error
__seh_init:
mov fs:[0], esp

call testmsgbox

__seh_error: pop dword ptr fs:[0]
pop eax ;

popa
retn

get_func_names:

lea esi, imp_name-virstart[ebp]
lea edi, imp_addr-virstart[ebp]

__cycle: call get_proc_address
jz __error
stosd

__scan0: lodsb
or al, al
jnz __scan0

cmp [esi], al
jne __cycle

__success: clc
retn

__error: stc
retn

get_proc_address:

pusha

sub esp, virmemory
mov ebx,[esp]
and ebx,0FFFF0000h

mov ecx, [ebx].mz_neptr
mov ecx, [ecx].pe_exporttablerva
add ecx, ebx

xor edi, edi
__search_cycle: lea edx, [edi*4]
add edx, [ecx].ex_namepointersrva
mov edx, [edx]
add edx, ebx

pusha
mov edi, edx
__cmp_cycle: cmp byte ptr [edi], 0
je __cmp_done
cmpsb
je __cmp_cycle
__cmp_done: popa

je __name_found

inc edi
cmp edi, [ecx].ex_numofnamepointers
jb __search_cycle

__return_0: xor eax, eax ; return 0
jmp __return

__name_found: mov edx, [ecx].ex_ordinaltablerva
add edx, ebx
movzx edx, word ptr [edx*2]
mov eax, [ecx].ex_addresstablerva
add eax, ebx
mov eax, [eax*4]
add eax, ebx

__return: mov [esp].popa_eax, eax
test eax, eax

popa
retn

testmsgbox:
xor eax,eax
push eax
push offset szTitle
push offset szMessage
push eax
call x_MessageBoxA-virstart[ebp]

imp_name:
db 'MessageBoxA',0
db 'CreateThread',0
db 0

align 4
virsize equ $-virstart

imp_addr:
x_MessageBoxA dd ?
x_CreateThread dd ?

align 4
virmemory equ $-virstart
.code
loader:
call virentry
end loader

В consts.inc находятся структуры для работы с PE
Без SEH есстественно вылетает...
Что не так... не могу понять, пропускал через Debuger


Дата: Июл 5, 2004 14:06:20

Неужели нет решения?!


Дата: Июл 5, 2004 21:39:09

Боюсь, многим просто влом все это читать и разбираться. Сужу по себе. Все-таки я бы хотел увидеть более конструктивный вопрос. В ветке про PE вирус я постил кусок виря с поиском кернела и апи, но народ что-то не может разобраться. Автора того куска (сарс) вот на вас нет. :)

Предлагаю тебе посмотреть все это дело (твой код) хорошенько, найти места, где случается что-то не то, а если не поймешь сам - задавай вопрос, попробую помочь. Честное слово, лично у меня сейчас в голове достаточно весомый проект и ресурсов на копание в чужом коде просто не хватает. Думается, у остальных тоже.


Дата: Июл 7, 2004 13:46:39

choor
> Неужели нет решения?!

Методы поиска API давно описаны, есть примеры, например у y0da.


Дата: Июл 7, 2004 15:12:01

2n0p: не могу разобраться где падает программа.
2Asterix: а ссылочку?


Дата: Июл 7, 2004 18:49:43


Дата: Июл 8, 2004 10:14:33

Ну а отладчик человеку на что дан? Проходишь по шагам, находишь место падения, смотришь код вокруг и думаешь, что такое не так. Если она вылетает с ошибкой доступа к памяти - ищи кривую адресацию у себя, часто такие эксепшены в апишках вылезают, если ей вместо адреса сунуть значение.

Ок, посмотрел я твой код немного.
Интересный у тебя способ получать базу кернела. Он вобще работает? Сдается мне, что не очень-то он работает..
Зачем делать кучу call'ов, если они делаются один раз? почему нельзя все оформить прямым кодом? И раз уж ты делаешь call, где-то должен быть ret, а иначе бардак получится. ИМХО, это не тот язык, где надо дробить все на процедурки по 2-3 инструкции..


Дата: Июл 22, 2004 09:16:21

А это можно только на АСме, или на делфи можно?


Дата: Июл 22, 2004 11:16:08

Насчет де#$фей не знаю, но на С++ точно можно. У SBVC видел пример поиска базы кернела (на сях), ну а поиск апишки в памяти - это элементарно. Вобщето, поиск кернела тоже сложностей не вызывает..


Дата: Июл 22, 2004 15:24:35

если кому надо на делфях, вот:
function GetKernelBase:dword;
const MIN_KERNEL_SEARCH_BASE = $70000000;
asm
    // looking for last SEH frame
    mov edx,fs:[0]
@NextSEH:
    mov eax,[edx+4]
    mov edx,[edx]
    cmp edx,$FFFFFFFF
    jnz @NextSEH
    // looking for base of kernel32
    and eax,$FFFF0000
@Circle:
    cmp word ptr [eax],5A4Dh
    jnz @NOT_IMAGE_DOS_SIGNATURE
    mov edx,eax
    add edx,[edx+3Ch]
    cmp dword ptr [edx],00004550h
    jz @Found
@NOT_IMAGE_DOS_SIGNATURE:
    sub eax,10000h
    cmp eax,MIN_KERNEL_SEARCH_BASE
    jnb @Circle
    mov eax,0BFF70000h
@Found:
end;

function GetProcAddr(DllBase:dword; Api:PChar):pointer; register;
const MAX_API_STRING_LENGTH = 150;
asm
  push ebx
  push esi
  push edi

  push edx
  push eax

  or eax,eax
  jz @BadExit

  mov esi,eax // DllBase
  cmp word ptr [esi],5A4Dh
  jnz @BadExit
  add esi,[esi+03Ch]
  cmp dword ptr [esi],00004550h
  jnz @BadExit

  // get the string length of the target Api
  mov edi,edx // Api
  mov ecx,MAX_API_STRING_LENGTH
  xor al,al
  repnz scasb
  mov ecx,edi
  sub ecx,edx // ECX -> Api string length

  // trace the export table
  mov edx,[esi+078h] // EDX -> Export table
  add edx,[esp]
  mov ebx, [edx+20h] // EBX -> AddressOfNames array pointer
  add ebx,[esp]
  xor eax,eax // EAX AddressOfNames Index

@Circle:
  mov edi,[ebx]
  add edi,[esp]
  mov esi,[esp+4] // Api
  push ecx // save the api string length
  repz cmpsb
  pop ecx
  jz @Found
  add ebx,4
  inc eax
  cmp eax,[edx+18h] // NumberOfNames
  jz @BadExit
  jmp @Circle
@Found:
  // find the corresponding Ordinal
  mov esi,[edx+24h] // AddressOfNameOrdinals
  add esi,[esp] // dwDllBase
  push edx // save the export table pointer
  mov ebx,2
  xor edx,edx
  mul ebx
  pop edx
  add eax,esi
  xor ecx,ecx
  mov cx,[eax] // ECX -> Api Ordinal

  // get the address of the api
  mov edi,[edx+1Ch] // AddressOfFunctions
  xor edx,edx
  mov ebx,4
  mov eax,ecx
  mul ebx
  add eax,[esp]
  add eax,edi
  mov eax,[eax]
  add eax,[esp]
  jmp @ExitProc
@BadExit:
  xor eax,eax
@ExitProc:
  add esp,8
  pop edi
  pop esi
  pop ebx
end;


хотя от делфей тут одно название :))
я сам писАл по мотивам самплов от йоды и т.п.
вообще, сколько можно обсасывать эту тему? примеров - мильон.
не работает? пивка бутылочку, отладчик и вперед!


Дата: Июл 22, 2004 23:25:21

а я на Си сделал семплик под мой любимый LCC+)) находим базовый адрес Кернел32... так для общей кучи...

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

typedef struct _SEH
{
struct _SEH *m_pSEH;
DWORD m_pExcFunction;
} SEH, *PSEH;

SEH *seh=NULL;

int main(int argc,char *argv[])
{
_asm("movl %fs:0,%eax");
_asm("movl %eax,%seh");
while((DWORD)seh->m_pSEH != 0xffffffff)
seh = seh->m_pSEH;
DWORD KERNEL_ENTRY=(seh->m_pExcFunction&0xFFFF0000);
PIMAGE_DOS_HEADER doshdr=(IMAGE_DOS_HEADER*)KERNEL_ENTRY;
if(*(WORD*)KERNEL_ENTRY!=IMAGE_DOS_SIGNATURE)
return 0;
if(*(DWORD*)(KERNEL_ENTRY+doshdr->e_lfanew)!=IMAGE_NT_SIGNATURE)
return 0;
printf("Kernel base adress is: 0x%x\n", KERNEL_ENTRY);
system("pause");
return 1;
}


Дата: Июл 23, 2004 13:40:16

„не работает? пивка бутылочку, отладчик и вперед!“
Вот это я и пытаюсь донести! Но не всем дано, видимо..


Дата: Июл 24, 2004 07:54:19

Насчёт кода на делфи, сейчас испробую


Дата: Июл 24, 2004 11:44:21


Дата: Июл 24, 2004 13:42:45

2 Max зашибись, работает, у тебя случаем ничего подобного ещё нет?


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.049