Assembler - Opcody problem

0

Witam, otóż chcę zmodyfikować opcode w pamięci procesu, w tym samym procesie, żeby w trakcie działania wykonała się inna instrukcja. Przy segmencie danych to działa, jednak jak próbuję z segmentem kodu to program mi się crashuje. Nie wiem czy źle modyfikuję instrukcję, czy wynika to z ograniczenia OS. Prosiłbym o pomoc.

00401000 B8 05 MOV EAX, 5
...

mov al, 0BBh
mov ebx, 0401000h
mov cs:[ebx], al
0

przeczytaj wiadomosc na gg

0

Pogadalem z nim i wiem juz o co chodzi w uproszczeniu problem wyglada tak:

Mamy prosty kod w C++:

#include <cstdio>

extern "C"
{
  char* test();
}

int main()
{
  printf("%s\n", test());
  printf("%s\n", test());
  return 0;
}

I kod w ASM (kompilator: NASM):

global  _test


segment data

text1: DB "krzysiu1", 0
text2: DB "krwq", 0

segment code
input_start:
	mov eax, text2
input_end:

_test:
        push    ebp 
        mov     ebp, esp 

	output:
	mov eax, text1

	mov esi, input_start
	mov edi, output
	mov ecx, input_end-input_start
	cld
	rep movsb

	leave
	ret

chcialem zeby kod zmodyfikowal sam siebie zamieniajac instrukcje "mov eax, text1" na "mov eax, text2" (uproszczony przypadek, w ogolnosci po prostu ma kopiowac input do output, z zalozeniem ze oba maja taki sam rozmiar).

Po zlinkowaniu i odpaleniu output programu ma wygladac tak:

krzysiu
krwq

z asm jestem cienki. moge tylko powiedziec ze powyzszy kod sie crashuje i nie mam pomyslu jak to naprawic, moglby ktos pomoc? Czy moj kod jest bledny czy OS nie pozwala na modyfikacje segmentu .CODE? jesli opcja numer 2 to jak temu zapobiec? da sie jakos zezwolic na modyfikacje segmentu?

5

W przypadku Windows sekcja kodu jest faktycznie specjalnie chroniona. Żeby umożliwić zmodyfikowanie kodu trzeba:

  • wywołać funkcję VirtualProtect (za pomocą ostatniego argumentu najlepiej zapisać sobie poprzednią wartość)
  • zmodyfikować kod
  • przywrócić poprzednie uprawnienia
  • wywołać FlushInstructionCache

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms679350%28v=vs.85%29.aspx

0

chyba jednak z ASM dalej mam cos nie tak. Tutaj aktualny kod:
CPP:

#include <cstdio>
#include "windows.h"

extern "C"
{
  char* test();
  void* test_address();
  size_t test_size();
}

int main()
{
  DWORD old_prot,foo;
  void* address = test_address();
  size_t size = test_size();
  VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &old_prot);

  printf("%s\n", test());
  printf("%s\n", test());
  VirtualProtect(address, size, old_prot, &foo);
  FlushInstructionCache(GetCurrentProcess(), address, size);

  return 0;
}

ASM:

global  _test
global  _test_address
global  _test_size


segment data

text1: DB "krzysiu1", 0
text2: DB "krwq", 0

segment code
input_start:
	mov eax, text2
input_end:

_test:
        push    ebp 
        mov     ebp, esp 

output_start:
	mov eax, text1
output_end:

	mov esi, input_start
	mov edi, output_start
	cld
	mov cx, input_end-input_start
	rep movsb

	leave
	ret

_test_address:
	mov eax, output_start
	ret

_test_size:
	mov eax, output_end-output_start
	ret
3

Sorki, że nie poprawiłem twojego kodu, ale tak źle się czuję, że tylko wkleję ci to, co wcześniej sam naskrobałem.
Visual Studio + Masm

#include <iostream>
#include <Windows.h>

extern "C" char* TestFunc();
extern "C" size_t GetTestFuncLength();
extern "C" void ModifyTestFunc();

int main()
{
	size_t testFuncLength = GetTestFuncLength();
	DWORD oldProtect;

	std::cout << "TestFunc(): " << TestFunc() << "\n";

	VirtualProtect(&TestFunc, testFuncLength, PAGE_EXECUTE_READWRITE, &oldProtect);
	ModifyTestFunc();
	VirtualProtect(&TestFunc, testFuncLength, oldProtect, &oldProtect);
	FlushInstructionCache(GetModuleHandle(NULL), &TestFunc, testFuncLength);

	std::cout << "TestFunc(): " << TestFunc() << "\n";

	return 0;
}
.386
.model flat, c
.stack

.data

Text1 db "test1", 0
Text2 db "test2", 0

.code

InputStart:
	mov eax, offset Text2
InputEnd:

TestFunc proc
	mov eax, offset Text1
	ret
TestFunc endp
TestFuncEnd:

GetTestFuncLength proc
	mov eax, TestFuncEnd - TestFunc
	ret
GetTestFuncLength endp

ModifyTestFunc proc
	mov esi, InputStart
	mov edi, TestFunc
	mov ecx, InputEnd - InputStart

	cld
	rep movsb
	ret
ModifyTestFunc endp
 
end

1 użytkowników online, w tym zalogowanych: 0, gości: 1