배열 과 함수 포인터 형변환에 관해서..
글쓴이: oprsystem / 작성시간: 월, 2004/03/08 - 4:15오후
안녕하세요..
함수를 배열로 복사한뒤에 배열을 함수 포인터의 주소로 옴겨서 실행하려고 합니다.
테스트 해 보기위해서 VC6.0에서 작성하였습니다.
작성한 파일의 확장자는 CPP입니다.
제가 무엇을 잘못 하였는지 지적 부탁드리겠습니다.
int (*ramfunction)(); unsigned long RAM_FUNC_AREA[1000]; int RamFunc(); int EndRamFunc(); int main(int argc, char* argv[]) { memcpy((char *) RAM_FUNC_AREA,(char *) RamFunc, (int)((unsigned long)EndRamFunc - (unsigned long) RamFunc)); ramfunction = (int(*)())RAM_FUNC_AREA; ramfunction(); return 1; } int RamFunc() { printf("HI RAM AREA"); return 1; } int EndRamFunc() { #if 0 DUMMY #endif return 1; }[/b]
Forums:
기발한 아이디어입니다.안타깝게도.. 실행 불가능합니다.함수
기발한 아이디어입니다.
안타깝게도.. 실행 불가능합니다.
함수의 크기를 계산할 수 있는 방법은 존재하지 않으며,
함수의 내용을 변수에 복사하는 방법도 존재하지 않으며, 복사를 했다고 하더라도 그 코드를 실행할 수 있는 방법도 존재하지 않습니다.
이런 아이디어가 필요하시다면 C 대신에 lisp이나 scheme을 쓰시기 바랍니다.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
함수 포인터.
함수 포인터의 개념에 대해 잘못 생각하신듯 합니다.
일단 간단히 님의 소스를 변경해 보았는데.
이해를 도와줄 것입니다.
[quote="cinsk"]기발한 아이디어입니다.안타깝게도.. 실
음.. 저도 좀의문을 가졌었는데..
함수포인터의 주소는 실제 코드가 저장된위치가 아닌모양이지요..
----------------------------------------------------------------------------
안녕하세요..벌써 답글이 3개나 달렸네요.. 관심 감사 합니다.
안녕하세요..
벌써 답글이 3개나 달렸네요.. 관심 감사 합니다.
제가 미리 밝혔어야 하는데.. 저 코드는 저의 아이디어가 아니라 "Firmware Demystified" 라는 책에서 발췌한 내용 입니다. 제 불찰 입니다. 죄송합니다.
그리고.. 아직 해결 하지 못했습니다. :roll:
황혼보다 어두운 자여
내 몸에 흐르는 피보다 더 붉은 자여
시간의 흐름 속에 파뭍힌 위대한 그대의 이름을 걸고 나 여기서 어둠에 맹세하노라
우리 앞을 가로막고 있는 모든 어리석은 자 들에게
나와 그대의 힘을
위대한 파멸의 힘을 보여줄 것을
C++이라면
함수 포인터 대신에 함수 객체(function object)를 쓰면 가능하지요.
검색해보시길...
재밌는 기능인데, 제 생각은 함수 내의 내용에 따라 실행 되는 함수도 있
재밌는 기능인데, 제 생각은 함수 내의 내용에 따라 실행 되는 함수도 있을 것 같고 그렇지 않은 함수도 있을 것 같습니다.
즉, OS나 컴파일러등 여러 환경에 따라 특정 상태에서만 실행될 것이라는 얘기 입니다.
data segment가 실행가능한 경우가 보장되어야하고 (2004년 현재 대부분 그렇죠?)
이름이 뭐하지만, 대충 지어본다면 User level re-location 으로도 안전한 코드여야하고..
몇몇 조건만 만족하면 실행가능한 코드도 찾아 볼 수 있을 것 같은데요?
---
http://coolengineer.com
가능하지 않을까요?buffer overflow 코드들도 어셈으로
가능하지 않을까요?
buffer overflow 코드들도 어셈으로 작성되어 stack 메모리에서 실행하는 구조이니..
어셈으로 원하는 기능을 모두 구현하려면 꽤 힘들것 같기는합니다.
[code:1]#include <stdio.h>int &#
이렇게 하면 잘되는군요..! 왜 그런지는 assembly code를 잘 살펴보면 됩니다...
힌트는 메모리 이동이 일어나는 함수 안에는 상대 점프가 일어나지 않아야합니다.
---
http://coolengineer.com
아. .그렇군요..
아. .그렇군요..
황혼보다 어두운 자여
내 몸에 흐르는 피보다 더 붉은 자여
시간의 흐름 속에 파뭍힌 위대한 그대의 이름을 걸고 나 여기서 어둠에 맹세하노라
우리 앞을 가로막고 있는 모든 어리석은 자 들에게
나와 그대의 힘을
위대한 파멸의 힘을 보여줄 것을
혹시 아래의 에러에 대해 솔류션을 가지신분 없으신가요? (VC++6.0)
혹시 아래의 에러에 대해 솔류션을 가지신분 없으신가요? (VC++6.0)
C:\Program Files\Microsoft Visual Studio\MyProjects\aaasss\aaasss.cpp(22) : error C2440: 'type cast' : cannot convert from 'unsigned long [1000]' to 'int (__cdecl *)(void)'
There is no context in which this conversion is possible
Error executing cl.exe.
황혼보다 어두운 자여
내 몸에 흐르는 피보다 더 붉은 자여
시간의 흐름 속에 파뭍힌 위대한 그대의 이름을 걸고 나 여기서 어둠에 맹세하노라
우리 앞을 가로막고 있는 모든 어리석은 자 들에게
나와 그대의 힘을
위대한 파멸의 힘을 보여줄 것을
암시적 형변환이 일어나게 했나보죠?
암시적 형변환이 일어나게 했나보죠?
---
http://coolengineer.com
ramfunction = (int(*)())RAM_FUNC_AREA;
ramfunction = (int(*)())RAM_FUNC_AREA;
이런식으로 했습니다. VC++에서 나오는 에러네요
다른컴파일러는 그냥 넘어 가는데..
황혼보다 어두운 자여
내 몸에 흐르는 피보다 더 붉은 자여
시간의 흐름 속에 파뭍힌 위대한 그대의 이름을 걸고 나 여기서 어둠에 맹세하노라
우리 앞을 가로막고 있는 모든 어리석은 자 들에게
나와 그대의 힘을
위대한 파멸의 힘을 보여줄 것을
제가 지금 VC가 없어서... 확인을 못하겠군요.. :)
제가 지금 VC가 없어서... 확인을 못하겠군요.. :)
---
http://coolengineer.com
:D
:D
황혼보다 어두운 자여
내 몸에 흐르는 피보다 더 붉은 자여
시간의 흐름 속에 파뭍힌 위대한 그대의 이름을 걸고 나 여기서 어둠에 맹세하노라
우리 앞을 가로막고 있는 모든 어리석은 자 들에게
나와 그대의 힘을
위대한 파멸의 힘을 보여줄 것을
[quote="바람돌이"]ramfunction = (int(*)())RA
에러메시지처럼 'unsigned long [1000]'를 바로 'int (__cdecl *)(void)'로 바꾸지는 못합니다.
다음처럼 중간에 void*를 경유하게 해 보세요.
ramfunction = (int(*)())(void*)RAM_FUNC_AREA;
일단 에러는 나지 않을 겁니다.
그리고, 위의 코드를 windows상에서 실행시켰더니, 실행이 되질 않습니다.
문제를 찾아보니, 실제 코드영역으로부터 데이터영역으로의 복사가 수행되질 않습니다.
아무래도 OS에 따라 동작하는 내용이 달라질 듯한 내용인 것 같습니다.
제 테스트 환경은 WindowsXP Prof + VC++6.0 SP5 입니다.
저도 동작하지 않는군요.windows2000 server , VC
저도 동작하지 않는군요.
windows2000 server , VC++6.0 입니다.
황혼보다 어두운 자여
내 몸에 흐르는 피보다 더 붉은 자여
시간의 흐름 속에 파뭍힌 위대한 그대의 이름을 걸고 나 여기서 어둠에 맹세하노라
우리 앞을 가로막고 있는 모든 어리석은 자 들에게
나와 그대의 힘을
위대한 파멸의 힘을 보여줄 것을
흠.. 좀더 살펴보니 디버깅정보에 보여지는 함수포인터의 값과 런타임에 읽
흠.. 좀더 살펴보니 디버깅정보에 보여지는 함수포인터의 값과 런타임에 읽어오는 함수포인터의 값이 다르더군요.
그래서, 어셈블코드를 보니, 런타임에는 함수포인터를 모두 @ILT 를 통해서 접근하더군요... (ILT-Inline Table)
그러니, 복사가 제대로 안됐던 거였구요....
ILT접근을 조금 변경하면 될 것도 같긴 하네요....
저 내용이 쓰이는 부분
플래시 메모리에 있는 코드를 플래시 내용을 갱신시키기 위해서 사용할 경우 코드를 램으로 옮겨서 실행하는 경우가 필요한데 그러한 경우에 위의 방법처럼 사용하더군요. 임베디드 기기를 업그레이드 할 때 많이 쓰는 방식으로 알고 있는데 아마도 머신이나 OS, 컴파일러마다 방식이 다르게 나오지 않을까 하는 생각입니다.
저는 VC에서 잘 되는 걸요?제가 바꾼 것이라곤 memcpy 될
저는 VC에서 잘 되는 걸요?
제가 바꾼 것이라곤 memcpy 될 크기입니다.
그리고, 확장자는 .c 로 하여 c compiler를 사용하였습니다.
---
http://coolengineer.com
저도 잘되는 데요...Visual C++ 6.0 & windo
저도 잘되는 데요...
Visual C++ 6.0 & window 2000 SP3
확장자는 .cpp,
로 했습니다.
코드 메모리의 영역을 결정하는 부분에서 문제였군요.감사 합니다.
코드 메모리의 영역을 결정하는 부분에서 문제였군요.
감사 합니다.
황혼보다 어두운 자여
내 몸에 흐르는 피보다 더 붉은 자여
시간의 흐름 속에 파뭍힌 위대한 그대의 이름을 걸고 나 여기서 어둠에 맹세하노라
우리 앞을 가로막고 있는 모든 어리석은 자 들에게
나와 그대의 힘을
위대한 파멸의 힘을 보여줄 것을
댓글 달기