2012-03-18 4 views
0

C에서 나는 프로그램이 실행되는 동안 컴퓨터 명령을 직접 실행하는 방법이 필요합니다. 바이너리에서 컴퓨터 명령어를 만드는 방법을 알고있는 유일한 방법은 16 진 편집기를 사용하는 것입니다. 그러면 파일을 응용 프로그램으로 실행합니다. 어떻게하면 프로그램을 사용하여 이진 코드를 작성한 다음 실행을 위해 새 프로세스를 만들지 않고도이 코드를 실행할 수 있습니다. 이 작업을 수행하는 간단한 방법 인 것처럼 보이지만 어디에서든지 찾을 수 없습니다. 나는이 일을 생각할 수바이너리로 컴퓨터 명령을 직접 실행하십시오.

유일한 다른 방법은 인라인 어셈블리를 통해이지만, 내 현재 프로젝트에서 바이너리를 직접 실행, 단점이 될 갈 수있는 가장 좋은 방법입니다 것이라고. (이것은 아마도 리눅스에서 수행하는 방법 창?에 드라이버를 필요로? 즉 크로스 플랫폼 방법이 좋을 것이다)

감사합니다.

+1

inlince 어셈블리는 바이너리로 컴파일됩니다 인라인 어셈블리로 (확실히 가능 AFAIK되지 않음) 귀하의 기대에 비해 오버 헤드가 없습니다. –

+1

모든 명령은 실행될 때 "바이너리"로되어 있습니다. 성취하려는 것을 설명해 주시겠습니까? – Caleb

+1

스택을 부수십시오. –

답변

5

싶은 것은 조금 문제가 많은 사람들이 질문 할 책임이있다 "왜 그렇게하나요?"

당신이 (매우 드문) 메모리 보호없이 운영 체제가 가정하면, 당신은 단지 바이트의 배열에 대한 기능을 가리키고 함수를 호출 할 수 있습니다. 이런 일을 할 때 걱정 너무 많은 일이있다,

unsigned char* code_to_execute = "\xB8\x13\x00\xCD\x10"; 
void (*runCode)(); 

runCode = code_to_execute; 

runCode(); 

을하지만 : 여기의 요점이다. C 컴파일러가 함수 호출 프레임을 설정하고 "바이너리 코드"에서이를 존중하는 방법을 알아야합니다. 이런 방식으로 플랫폼 간 코드를 생성하는 것은 불가능합니다. 단일 플랫폼에서 여러 개의 C 컴파일러로 실행되는 경우조차 어렵습니다. 그리고 메모리 보호가 있습니다. 대부분의 최신 운영 체제는 단순히 임의로 데이터를 코드로 실행할 수 없습니다. 명시 적으로 메모리를 실행 가능으로 표시해야하며 많은 운영 체제가 특별한 허가없이 그렇게 할 수는 없습니다. 이 작업을 수행 할 수있는 플랫폼 간 방법도 없습니다.

다시 말해서, 저는 이것이 정말로 좋은 생각이 아니라고 강조하고 싶습니다. 인라인 어셈블리 언어를 사용하는 것이 좋습니다. 또는 어셈블리 언어를 전혀 사용하지 않는 것이 좋습니다. 어쩌면 프로젝트에 대해 더 설명 할 수 있고 C 프로그램에 직접 "바이너리 코드"를 쓰는 것이 중요한 이유가 될 수 있습니다. 그것은 우리가 당신을 상당히 도울 수있는 대답이나 추천을 만드는 데 도움이 될 것입니다.

+0

고맙습니다. 크로스 플랫폼의 의미는 모든 시스템에서 같은 방식으로 작동한다는 것이 아니라 단순히 dll을로드하거나 장치 드라이버를 만드는 것과 같은 플랫폼 의존적 인 방법이 아님을 의미합니다. 컴퓨터와 직접 연결되어있는 인공 지능에 필요합니다. 컴퓨터는 컴퓨터이므로 인공 지능 언어 (바이너리)를 사람이 읽을 수있는 (어셈블리)로 변환하여 컴퓨터에서 읽을 수있는 (바이너리) 것으로 변환해야하는 이유는 무엇입니까? 인공 지능은 OS 용으로 만들어 지므로 다른 프로세서의 작동 방식에 대한 걱정은 중요하지 않습니다. – u8sand

+2

궁금하다면 DOS COM 파일을 컴파일하여 DOS에서 실행할 수 있다면이 예제 코드가 실제로 작동합니다. 비디오 모드를 320x200, 256 색으로 변경합니다. B8은 "mov ax", 1300은 도끼로 이동하는 16 비트 값입니다. CD는 "콜 인터럽트"이고 10은 VGA 컨트롤러의 비디오 카드 인터럽트입니다. –

+0

이제 캐스팅 할 필요가 없다는 것이 궁금합니다. 아직 실제로 시도하지는 않았지만. – u8sand

2

메모리에있는 기계 코드를 사용하여 주소를 함수 포인터로 캐스트합니다. 물론 C 호출 규칙을 따라야합니다.

대부분의 데스크탑 운영체제에

, 당신은 그것을 실행 파일, 예를 표시하는 메모리 권한을 변경해야합니다 Windows의 경우 VirtualProtect 및 Linux의 경우 mprotect으로 전화하십시오.

이진 시스템 명령어는 플랫폼을 교차하지 않습니다. 각 프로세서 아키텍처마다 다른 코드를 생성해야합니다.

는 어떤 드라이버가 한 코드는 사용자 수준의 권한이 필요로 필요하지 않습니다.

+0

글쎄, 나는 이진 명령어가 크로스 플랫폼이 아니라는 것을 알고있다. 기본적으로 "컴퓨터 자체와 대화"하는 방법이 필요합니다. 그러나 당신이 dll을 로딩하는 것과 같은 소리를내는 방법은 프로그램에 바이너리를 어떻게 가져올 것인가? 쉘 코드와 같은 바이트 배열에 직접 넣을 것인가? – u8sand

+0

@ u8sand : 바이트 배열이 작동합니다. Andy와 같은 문자열이 그의 대답에 나타납니다. 실행 권한이 페이지 단위이기 때문에 자신의 페이지에 할당하는 것이 좋지만 절대적인 요구 사항은 아닙니다. –

4

이 그래서 질문은 아마도

How to write self-modifying code in x86 assembly

해달라고 당신은이 ...

"왜이 질문을하고있다"참조에 대해 충분히 알고 사람들이 당신을 늦출 수 있도록 주제를 다루고 언어 또는 운영 체제 또는 둘 모두를 사용하고 보호 시스템 내에서 펀치 스루하거나 작업하십시오.그렇다면 실행하고자하는 바이너리를 넣는 문제입니다 (주어진 위치/발견 된/획득 된/무엇이든간에 메모리를 독립적으로 그리고/또는 의존적으로하는 작업을했다고 가정). C에서 함수 포인터를 선언하고이 바이너리의 주소가되는 함수에 주소를 할당 한 다음 함수를 호출 할 수 있습니다 (주소로 분기 할 수있는 다른 방법이 없다면 대개 asm과 asm을 통과하는 임의의 주소로 브랜치를 수행하는 링크).

2

런타임에 응용 프로그램 내에서 코드를 생성하고 실행하는 것은 꽤 잘 알려진 문제입니다.

웹에서 "시간 컴파일러"또는 "JIT 컴파일", "동적 코드 생성"을 검색하여 코드 생성 및 실행 중에 많은 정보를 찾을 수 있습니다. 'Java'와 같은 프로그래밍 언어 이름.

동적 코드 생성은 지난 15 년간의 뜨거운 연구 주제 중 하나입니다.

Java 런타임 시스템 (Java Virtual Machine 또는 JVM이라고 함)은 동적 컴파일 기술 (HotSpot)을 사용하여 획기적으로 향상된 (즉, 10 배 이상) 성능을 얻습니다.

Microsoft는 C#과 같은 .NET 용 Just-In-Time 컴파일을 사용하지만 자세한 정보를 찾기가 어려울 수 있습니다.

Ian Piumarta SmallTalk의 '아버지'인 Alan Kay와 협력하여 매우 인상적인 동적 컴파일 기술 (예 : Cola)을 개발했습니다. SmallTalk (Small Talk는 현대 Windowing Systems 및 일부 유형의 객체 지향 프로그래밍 언어의 시작점입니다.). 이 기술 중 일부는 Google Summer of Code 프로젝트에서 카이로 렌더링 엔진 (웹 브라우저 등에서 사용됨)의 속도를 높이기 위해 사용되었습니다.

Ian Piumarta의 작품은 가장 유연하고 컴팩트하므로 시작하기 좋은 장소 일 수 있습니다. 이안은 믿을 수 없을만큼 영리하다고 경고하십시오. 사용하고 싶다면 열심히 생각할 준비를하십시오. 수도

다른 기술 :

몇 JIT의 어셈블러 (하지만 난 그들을 사용한 적이) 정확히 당신이 필요로 할 수있다 생성되는이 있습니다 보기 가치가 있습니다 :

  • LLVM
  • Google V8 JavaScript Engine는 LLVM의 JIT와 GNU의 libjit 최고의 정상 '호스트'환경 외부에서 사용하기 위해 문서화 아마. LLVM은 Apple의 기술 지원입니다. LLVM은 다른 시스템을 구축하는 데 사용할 수 있도록 라이브러리 집합에서 어셈블되도록 설계되었습니다. 그러나 이것은 매우 정교하고 고성능 인 솔루션을 목표로하므로 가파른 학습 곡선이 예상됩니다. GNU libjit은 작아 보이고 그로 인해 이해하기 쉽습니다. 나는 단지 인텔의 ORP를 발견했다.

    HTH

  • 관련 문제