학습 어셈블리 [닫기]


102

나는 어셈블리 언어를 배우기로 결정했습니다. 그렇게하는 주된 이유는 디스 어셈블 된 코드를 이해하고 코드의 더 효율적인 부분 (예 : C ++를 통해)을 작성할 수 있고 코드 동굴과 같은 작업을 수행 할 수 있기 때문입니다. 어셈블리에는 수많은 종류가 있습니다. , 내가 언급 한 목적을 위해 어떻게 시작해야합니까? 어떤 종류의 어셈블리를 배워야합니까? 먼저 간단한 프로그램 (예 : 계산기)을 수행하여 배우고 싶지만 목표 자체는 예를 들어 IDA Pro가 보여주는 코드를 이해할 수 있도록 그것에 익숙해지는 것입니다.

나는 창문을 사용하고 있습니다 (그게 차이가 있다면).

편집 : 그래서 모든 사람들이 MASM을 가리키는 것 같습니다. 높은 수준의 기능이 있고 어셈블리 코드 프로그래머에게 모두 좋다는 점을 알지만, 그것은 내가 찾던 것이 아닙니다. 인기있는 디 어셈블러 (IDA와 같은)에 표시되지 않은 if, invoke 등의 명령어가있는 것 같습니다. 그래서 가능한 한 듣고 싶은 것은 "일반적인"어셈블리 프로그래머가 아니라 내가 요청하는 목적 (IDA에서 분해 된 exe의 코드 읽기)을 위해 ASM을 사용하는 사람의 의견입니다.

편집 : 좋아. 나는 이미 어셈블리를 배우고 있습니다. 나는 나에게 중요하지 않은 높은 수준의 물건을 사용하지 않고 MASM을 배우고 있습니다. 지금 제가하고있는 일은 C ++의 __asm ​​지시문에 대한 코드를 시험해 보는 것이므로 MASM으로 모든 것을 처음부터해야하는 것보다 훨씬 빠르게 시도 할 수 있습니다.



예, 저도 읽었습니다. 그러나 내 질문은 좀 더 "집중"하다고 말하고 싶습니다.
삼켜 진 elysium

Windows를 사용하는 경우 대상 (즉, 프로세서 및 명령 집합)은 x86 또는 x86-64입니다. 다른 기계 또는 MCU 보드를 얻거나 에뮬레이터를 사용하지 않는 한. 그렇다면 어떤 어셈블러 를 사용해야합니까? 아니면 실제로 어떤 아키텍처를 대상으로 할 것인지 묻고 있습니까? 개인적으로 나는 m68k 시리즈 칩에 대한 멋진 직교 명령 세트를 좋아합니다.
dmckee --- ex-moderator kitten

2
"if, invoke 등의 명령어가있는 것 같습니다."-매크로 ( "MASM"의 'M')이며 어셈블러에서 지원하더라도 사용할 필요가 없습니다.
ChrisW

3
이 질문에 65 번째 찬성표를 던지는 것은 어려운 결정이었습니다. 64는 정말 아름다운 숫자입니다. . .
735Tesla 2014 년

답변:


40

MASM32로 시작하고 거기서부터 FASM을 살펴보십시오 . 그러나 당신은 MASM으로 재미있게 지낼 것입니다.


MASM에서 들었습니다. 내가 착각하지 않았다면 디스 앰블 된 코드를 볼 때 볼 수없는 "고수준"기능이 많이 있습니다. 이것이 의미가 있다면 대부분의 디스어셈블러 출력 코드와 똑같은 것으로 프로그래밍하고 싶습니다.
삼켜 진 elysium

1
그것은 기본적으로 op 코드를 작성하는 것과 같지만 실제로는 말이되지 않습니다. MASM32를 배우면 디버거에서 코드가 어떻게 보이는지 이해하는 데 도움이됩니다. OllyDbg도 확인하실 수 있습니다 : ollydbg.de
Noon Silk

7
어셈블리를 이해하지 못합니다. 당신은 그것을 이해해야합니다. opcode는 숫자입니다. 디버거는 명령에 대한 opcode를 해결하려고 시도합니다 (때로는 어렵습니다). 기본 지침을 이해해야합니다. MASM을 배우면이를 수행하는 데 도움이됩니다. 더 이상 말할 필요가 없습니다.
Noon Silk

5
MASM 기능이 있다는 이유만으로 모든 MASM 기능을 사용할 필요는 없습니다. 그런 식으로 더 많이 배울 것이라고 생각한다면, 원하는대로 읽기 어렵게 만들 수 있습니다.
JasonTrue

3
특기 사항, 버그 및 소위 고급 기능을 갖춘 MASM은 내가 생각할 수있는 그 무엇보다 어셈블리 프로그래머 (초보자 및 전문가 모두)를 혼동하는 데 더 많은 일을했습니다.
IJ Kennedy

44

나는 이것을 여러 번했고 이것을 계속한다. 이 경우 기본 목표가 어셈블러를 작성하지 않고 읽는 것입니다.

자신 만의 디스어셈블러를 작성하십시오. 다음으로 위대한 디스어셈블러를 만들기위한 것이 아니라, 이것은 엄격히 당신을위한 것입니다. 목표는 명령어 세트를 배우는 것입니다. 새로운 플랫폼에서 어셈블러를 배우 든, 한때 알고 있던 플랫폼의 어셈블러를 기억합니다. 몇 줄의 코드로 시작하고, 예를 들어 레지스터를 추가하고, 바이너리 출력을 분해하고 입력 측에 점점 더 복잡한 명령어를 추가하는 사이에 핑퐁을 사용합니다.

1) 특정 프로세서에 대한 명령어 세트 학습

2) 모든 명령어에서 모든 opcode 비트를 흔들 수 있도록 해당 프로세서에 대해 어셈블에서 코드를 작성하는 방법의 뉘앙스를 배웁니다.

3) 그 명령 세트를 사용하여 생계를 유지하는 대부분의 엔지니어보다 명령 세트를 더 잘 배웁니다.

귀하의 경우 몇 가지 문제가 있습니다. 일반적으로 ARM 명령어 세트를 시작하는 것이 좋습니다. 오늘 출하되는 ARM 기반 제품이 다른 어떤 것보다 많습니다 (x86 컴퓨터 포함). 그러나 현재 ARM을 사용하고 있고 ARM이 수행하려는 작업에 도움이 될 수도 있고 도움이되지 않을 수도 있다는 것을 알고있는 시작 코드 또는 기타 루틴을 작성하기에 충분한 어셈블러를 알지 못할 가능성이 있습니다. ARM 우선의 두 번째이자 더 중요한 이유는 명령어 길이가 고정 된 크기이고 정렬되기 때문입니다. x86과 같은 가변 길이 명령어를 분해하는 것은 첫 번째 프로젝트로 악몽이 될 수 있으며 여기서 목표는 연구 프로젝트를 만들지 않는 명령어 세트를 배우는 것입니다. 세 번째 ARM은 잘 수행 된 명령어 세트이며 레지스터는 동일하게 생성되며 개별적인 특별한 뉘앙스가 없습니다.

따라서 시작하려는 프로세서를 파악해야합니다. msp430 또는 ARM을 먼저 제안하고 ARM을 먼저 또는 두 번째로 x86의 혼돈을 제안합니다. 어떤 플랫폼을 사용하든 사용할 가치가있는 모든 플랫폼에는 명령 세트와 연산 코드 (기계 언어의 비트 및 바이트) 인코딩이 포함 된 공급 업체에서 무료로 제공하는 데이터 시트 또는 프로그래머 참조 설명서가 있습니다. 컴파일러가하는 일과 컴파일러가 고생 할 필요가없는 코드를 작성하는 방법을 배우기 위해서는 몇 가지 명령어 세트를 알고 각 최적화를 통해 각 컴파일러의 각 명령어 세트에서 동일한 상위 레벨 코드가 어떻게 구현되는지 확인하는 것이 좋습니다. 환경. 하나의 컴파일러 / 플랫폼에 대해서는 더 좋게 만들었지 만 다른 모든 것에 대해서는 훨씬 더 나쁘게 만들기 위해 코드를 최적화하는 것을 원하지 않습니다.

ARM과 같이 또는 msp430과 같이 2 바이트마다 메모리를 통해 단순히 처음부터 시작하여 4 바이트 워드마다 선형 적으로 분해하는 대신 가변 길이 명령어 세트를 분해하는 것이 좋습니다 (msp430에는 가변 길이 명령어가 있지만 여전히 인터럽트 벡터 테이블의 진입 점에서 시작하면 메모리를 통해 선형으로 이동). 가변 길이의 경우 벡터 테이블 또는 프로세서 부팅 방법에 대한 지식을 기반으로 진입 점을 찾고 실행 순서대로 코드를 따르고 싶습니다. 사용 된 바이트 수를 알기 위해 각 명령어를 완전히 디코딩해야합니다. 그러면 명령어가 무조건 분기가 아닌 경우 해당 명령어 이후의 다음 바이트가 다른 명령어라고 가정합니다. 가능한 모든 분기 주소도 저장해야하며 자세한 지침을 위해 시작 바이트 주소라고 가정해야합니다. 한 번 성공했을 때 바이너리를 여러 번 통과했습니다. 진입 점에서 시작하여 해당 바이트를 명령어의 시작으로 표시 한 다음 무조건 분기에 도달 할 때까지 메모리를 통해 선형으로 디코딩했습니다. 모든 분기 대상은 명령어의 시작 주소로 태그가 지정되었습니다. 새 분기 대상을 찾을 수 없을 때까지 바이너리를 여러 번 통과했습니다. 언제라도 3 바이트 명령어를 찾았지만 어떤 이유로 두 번째 바이트를 명령어의 시작으로 태그 한 경우 문제가 있습니다. 코드가 상위 수준의 컴파일러에 의해 생성 된 경우 컴파일러가 악의적 인 작업을 수행하지 않는 한 발생해서는 안됩니다. 코드에 손으로 작성된 어셈블러 (예 : 오래된 아케이드 게임)가있는 경우 r0 = 0과 같이 발생하지 않는 조건부 분기가있을 수 있으며 0이 아니면 점프가 이어질 수 있습니다. 계속하려면 바이너리에서 직접 편집해야 할 수도 있습니다. 내가 x86에 있다고 가정하는 즉각적인 목표에 대해서는 문제가 있다고 생각하지 않습니다.

gcc 도구를 권장합니다. mingw32는 x86이 대상인 경우 Windows에서 gcc 도구를 사용하는 쉬운 방법입니다. mingw32 plus msys는 binutils 및 gcc 소스에서 크로스 컴파일러를 생성하기위한 훌륭한 플랫폼입니다 (일반적으로 매우 쉽습니다). mingw32는 훨씬 빠른 프로그램과 같이 cygwin에 비해 몇 가지 장점이 있으며 cygwin dll 지옥을 피할 수 있습니다. gcc 및 binutils를 사용하면 C 또는 어셈블러로 작성하고 코드를 디스 어셈블 할 수 있으며 세 가지 중 하나 또는 모두를 수행하는 방법을 보여주는 웹 페이지가 읽을 수있는 것보다 많습니다. 가변 길이 명령어 세트로이 작업을 수행하려면 디스어셈블러가 포함 된 도구 세트를 사용하는 것이 좋습니다. 예를 들어 x86 용 써드 파티 디스어셈블러는 올바르게 디스 어셈블되었는지 알 수 없기 때문에 사용하기 어려울 것입니다. 이 중 일부는 운영 체제에 따라 다르며, 목표는 디스어셈블러가보다 정확한 작업을 수행 할 수 있도록 데이터의 정보 표시 명령을 포함하는 이진 형식으로 모듈을 컴파일하는 것입니다. 이 기본 목표에 대한 다른 선택은 검사를 위해 어셈블러로 직접 컴파일 할 수있는 도구를 보유한 다음 바이너리 형식으로 컴파일 할 때 동일한 명령어를 생성하기를 바라는 것입니다.

질문에 대한 짧은 (약간 짧게) 답변입니다. 디스어셈블러를 작성하여 명령어 세트를 학습하십시오. 나는 ARM처럼 위험하고 배우기 쉬운 것으로 시작합니다. 하나의 명령어 세트를 알게되면 다른 명령어 세트를 훨씬 쉽게 선택할 수 있습니다. 종종 몇 시간 안에 세 번째 명령어 세트를 통해 구문에 대한 데이터 시트 / 참조 매뉴얼을 사용하여 거의 즉시 코드 작성을 시작할 수 있습니다. 사용할 가치가있는 모든 프로세서에는 연산 코드의 비트 및 바이트에 대한 지침을 설명하는 데이터 시트 또는 참조 설명서가 있습니다. ARM과 같은 RISC 프로세서와 x86과 같은 CISC를 배우면 모든 것에 대해 레지스터를 거쳐야하거나 레지스터가 적거나없는 메모리에서 직접 연산을 수행 할 수있는 것과 같은 차이점을 충분히 느낄 수 있습니다. 세 개의 피연산자 명령어 대 두 개 등. 높은 수준의 코드를 조정할 때 둘 이상의 프로세서에 대해 컴파일하고 출력을 비교합니다. 여러분이 배우게 될 가장 중요한 것은 높은 수준의 코드가 아무리 잘 작성 되더라도 컴파일러의 품질과 최적화 선택이 실제 명령어에 큰 차이를 만든다는 것입니다. llvm 및 gcc (binutils 포함)를 권장하지만 생성하지 않습니다.훌륭한 코드이지만 다중 플랫폼 및 다중 대상이며 둘 다 최적화 프로그램이 있습니다. 그리고 둘 다 무료이며 다양한 대상 프로세서의 소스에서 크로스 컴파일러를 쉽게 빌드 할 수 있습니다.


답장을 보내 주셔서 감사합니다. 하지만 디스어셈블러를 작성하는 방법도 모릅니다.
삼켜 진 elysium

8
"나만의 디스어셈블러 작성"-동의합니다. 이것이 제가 가장 잘 배운 방법입니다. ( "하지만 디스어셈블러를 작성하는 방법도 모르겠어요"는 무슨 일입니까?) LOL.
slashmais

나는 당신과 함께 간다! 그냥 MSP430과에 대한 책 ... :) 구입
페페

1
좀 MSP430 예는이 github.com/dwelch67 등 학습 ASM을 포함하여 실험을위한 플러스 몇 가지 명령어 집합 시뮬레이터
old_timer

이 아이디어가 정말 좋아요.
Millie Smith

33

손으로 작성하는 어셈블리와 컴파일러에서 생성 한 어셈블리는 높은 수준에서 볼 때 종종 매우 다릅니다. 물론, 프로그램의 내부는 매우 유사 할 것입니다 (결국 인코딩하는 방법은 매우 다양 a = b + c합니다).하지만 리버스 엔지니어링을 시도 할 때 문제가되지는 않습니다. 컴파일러가 추가됩니다 도 간단한 실행 파일에 상용구 코드를 : 어셈블리에 손으로 쓴 경우는 약 100 바이트의 동안 비교 마지막 시간, GCC에 의해 컴파일에 "Hello World"는 4kB의에 대해이었다. Windows에서는 더 나쁩니다. 마지막으로 비교했을 때 (확실히 이것은 지난 세기였습니다.) 내가 생성 할 Windows 컴파일러를 얻을 수있는 가장 작은 "Hello World"는 52kB였습니다! 일반적으로이 상용구는 한 번만 실행되므로 프로그램 속도에 큰 영향을주지 않습니다. 위에서 말했듯이 프로그램의 핵심 인 실행 시간이 가장 많이 소요되는 부분은 일반적으로 컴파일 또는 손으로 쓴다.

결국 이것은 전문 어셈블리 프로그래머 와 전문 디스어셈블러 가 서로 다른 두 가지 전문 분야 라는 것을 의미합니다 . 일반적으로 같은 사람에게서 발견되지만 실제로는 분리되어 있으며 훌륭한 어셈블리 코더가되는 방법을 배우는 것은 리버스 엔지니어링을 배우는 데 그다지 도움이되지 않습니다.

원하는 것은 IntelAMD 의 IA-32 및 AMD64 (둘 다 함께 다룹니다) 아키텍처 설명서를 가져 와서 지침 및 opcode에 대한 초기 섹션을 살펴 보는 것입니다. 어셈블리 언어의 기초를 이해하기 위해 어셈블리 언어에 대한 자습서를 한두 개 읽을 수 있습니다. 그런 다음 작은관심있는 샘플 프로그램을 분해하고 제어 흐름을 단계별로 살펴보고 무엇을하는지 이해하려고합니다. 다른 작업을 수행하기 위해 패치 할 수 있는지 확인하십시오. 그런 다음 다른 프로그램으로 다시 시도하고 더 유용한 목표를 달성 할 수있을만큼 편안해질 때까지 반복하십시오. 리버스 엔지니어링 커뮤니티에서 제작 한 "크랙"과 같은 것에 관심이있을 수 있습니다. 리버스 엔지니어링에 관심이있는 사람들이 직접 시도해보고 그 과정에서 무언가를 배우기를 바랍니다. 난이도는 기본 (여기서 시작하세요!)에서 불가능까지 다양합니다.

무엇보다도, 당신은 할 필요가 연습 . 다른 많은 분야에서와 마찬가지로 리버스 엔지니어링을 사용하면 연습이 완벽하거나 적어도 더 좋습니다 .


고급 언어로 무엇이든 컴파일 할 때 필요하지 않은 많은 "쓰레기"코드가 어셈블리에서 직접 코딩된다는 것을 알고 있습니다. 또한 전문 어셈블리 프로그래머와 전문 디스어셈블러간에 차이가 있다는 것도 이해합니다. 그러나 거의 모든 것에 대해서도 마찬가지입니다.
삼켜 진 elysium 09.01.09

3
나의 우려는 이론적으로는 논문을 읽고 그 의미를 이해할 수 있었지만, 내가 직접 글을 쓰기 시작할 때까지는 내가 그것을 진정으로 이해할 것이라고 믿지 않는다는 것입니다. 코드의 작은 부분을 변경하는 것으로 시작할 수 있다고 말씀 하셨지만,이를 위해서는 먼저 IDA pro가 어떤 종류의 어셈블리 "맛"을 사용하는지 알아야합니다.
삼켜 진 elysium 09.01.09

또한 MSVC ++는 인라인 어셈블리 코드에 무엇을 사용합니까? MASM?
삼켜 진 elysium

15

나는 대부분의 대답에 반대하고 Knuth의 MIPS RISC 아키텍처 의 MMIX 변형을 권장 합니다. x86 또는 ARM 어셈블리 언어만큼 실질적으로 유용하지는 않을 것입니다 (요즘 대부분의 실제 작업에서 그 자체로 중요하다는 것은 아닙니다 ... ;-). 알고리즘과 데이터 구조에 대한 깊은 저수준 이해에 관한 역사상 가장 위대한 걸작의 버전 인 TAOCP , "컴퓨터 프로그래밍 기술". 내가 인용 한 두 URL의 링크는 이러한 가능성을 탐색하는 좋은 방법입니다!


12

(당신은 모르지만 조립에 신이 났어요)

조립을 실험하기위한 간단한 도구가 이미 PC에 설치되어 있습니다.

시작 메뉴-> 실행으로 이동하여debug

debug (명령)

debug 는 DOS, MS-DOS, OS / 2 및 Microsoft Windows (x64가 아닌 x86 버전 만 해당)의 명령으로 debug.exe (또는 이전 버전의 DOS에서는 DEBUG.COM)를 실행합니다. 디버그는 어셈블러, 디스어셈블러 또는 16 진 덤프 프로그램으로 작동하여 사용자가 메모리 내용 (어셈블리 언어, 16 진수 또는 ASCII)을 대화식으로 검사하고 변경하고 COM, EXE 및 기타 파일 형식을 선택적으로 실행할 수 있도록합니다. 또한 특정 디스크 섹터, I / O 포트 및 메모리 주소에 액세스하는 데 사용되는 여러 하위 명령이 있습니다. MS-DOS 디버그는 16 비트 프로세스 수준 에서 실행 되므로 16 비트 컴퓨터 프로그램으로 제한됩니다 . FreeDOS Debug에는 32 비트 DPMI 프로그램도 지원하는 "DEBUGX"버전이 있습니다.

튜토리얼 :


IDA Pro (또는 OllyDbg ) 에서 볼 수있는 코드를 이해하려면 컴파일 된 코드가 어떻게 구성되는지 배워야합니다. Reversing : Secrets of Reverse Engineering 책을 추천합니다 .

저는 debug어셈블리를 배우기 시작했을 때 (15 년 전) 몇 주 동안 실험했습니다 .
참고 것을 debug기본 시스템 수준의 작품, 더 높은 수준의 어셈블리 명령이 없습니다.

이제 간단한 예제 :

부여 a어셈블리 코드를 작성 시작 - 프로그램 아래를 입력 - 마지막 줄 g을 실행합니다.

대체 텍스트


( 레지스터가 설정된 경우 레지스터에 INT 21저장된 ASCII 문자를 화면에 표시 - 프로그램 종료)DLAH2INT 20


"g"를 입력하기 전에 ctrl-c를 눌러야했습니다.
ericp

2
@ericp, ctrl-c를 누를 필요가 없습니다. 예를 들어, a어셈블리 코드 작성을 시작하려면 & [enter]를 입력합니다. [enter]를 두 번 누르면 조립 모드가 종료됩니다. g& [enter]를 눌러 실행합니다 (기본적으로 오프셋 100).
Nick Dandoulakis

실제로 스택 오버플로가 발생합니까 아니면 화면에 기록됩니까?
Janus Troelsen 2011 년

1
@user, 그냥 :-)이 사이트의 이름을 기록합니다
닉 Dandoulakis

@JanusTroelsen이 숫자 (53, 74, 61 등)는 'S' 't' 'a'에 대한 ASCII 코드입니다 ... 각 Int21 호출은 한 번에 한 문자를 인쇄합니다! 이것이 어셈블리가 더 빠르지 않은 이유입니다. :)
doug65536 2013 년

8

저는 Hacking : The Art of Exploitation 이이 주제에 대해 흥미롭고 유용한 방법이라는 것을 알았습니다 ... 제가 지식을 직접 사용한 적이 있다고 말할 수는 없지만 그것이 제가 그것을 읽은 이유는 아닙니다. 코드가 컴파일되는 지침을 훨씬 더 풍부하게 이해할 수 있으며, 이는 때때로 미묘한 버그를 이해하는 데 유용했습니다.

제목으로 미루지 마십시오. 이 책의 첫 번째 부분의 대부분은 Eric Raymond라는 단어의 의미에서 "해킹"입니다. 어려운 문제를 해결하는 창의적이고 놀랍고 거의 교활한 방법입니다. 저 (그리고 아마도 당신)는 보안 측면에 훨씬 덜 관심을 가졌습니다.


7

적어도 처음에는 어셈블리로 프로그램을 작성하는 데 집중하지 않을 것입니다. x86을 사용하는 경우 (Windows를 사용하고 있기 때문에 그렇다고 가정합니다) 배우는 것이 무의미한 이상한 특수 사례가 많이 있습니다. 예를 들어 많은 명령어는 명시 적으로 이름을 지정하지 않은 레지스터에서 작동한다고 가정하고 다른 명령어는 일부 레지스터에서는 작동하지만 다른 명령어에서는 작동하지 않는다고 가정합니다.

나는 당신이 의도 한 아키텍쳐에 대해 당신이 기초를 이해하는만큼 충분히 배운 다음 바로 들어가서 컴파일러의 출력을 이해하려고 노력할 것입니다. 인텔 매뉴얼로 무장 하고 컴파일러의 출력으로 바로 들어가십시오. 관심있는 코드를 작은 함수로 분리하면 전체 내용을 확실히 이해할 수 있습니다.

기본 사항은 다음과 같습니다.

  • 레지스터 : 몇 개가 있고, 이름이 무엇이며, 크기가 무엇입니까?
  • 피연산자 순서 : add eax, ebx"eax에 ebx를 추가하고 결과를 eax에 저장"을 의미합니다.
  • FPU : 부동 소수점 스택의 기본 사항과 fp로 /에서 변환하는 방법을 배웁니다.
  • 주소 지정 모드 : [base + offset * multiplier], 그러나 multiplier는 1, 2 또는 4 (또는 8?) 만 가능합니다.
  • 호출 규칙 : 매개 변수가 함수에 어떻게 전달됩니까?

많은 시간 동안 컴파일러가 무엇을 내보내는 지 놀라 울 것입니다. 왜 컴파일러가 이것이 좋은 생각이라고 생각했는지 알아내는 퍼즐을 만드십시오. 그것은 당신에게 많은 것을 가르쳐 줄 것입니다.

또한 Agner Fog의 설명서 , 특히 지침 목록에있는 설명서 로 무장하는 것도 도움이 될 것입니다 . 최신 프로세서에서 직접 수량화하기는 더 어렵지만 각 명령어의 대략적인 비용을 알려줍니다. 그러나 예를 들어 컴파일러가 idiv명령어 발행을 피하기 위해 그렇게 멀리 나가는 이유를 설명하는 데 도움이 될 것 입니다.

저의 유일한 조언은 선택권이있을 때 항상 AT & T 대신 인텔 구문을 사용하는 것입니다. 나는이 점에 대해 꽤 중립적이었다. 몇 가지 명령어가 둘 사이에 완전히 다르다는 것을 깨달을 때까지 (예를 들어 movslqAT & T 구문은 movsxdIntel 구문에 있음). 매뉴얼은 모두 인텔 구문을 사용하여 작성되었으므로 그대로 유지하십시오.

행운을 빕니다!


3

저는 매우 컴팩트 한 32 비트 아키텍처 인 MIPS를 배우기 시작했습니다. 축소 된 명령어 세트이지만 초보자도 쉽게 이해할 수 있습니다. 복잡성에 압도되지 않고 어셈블리가 어떻게 작동하는지 이해할 수 있습니다. MIPS 코드를 컴파일 할 수있는 멋진 IDE를 다운로드 할 수도 있습니다. clicky 일단 익숙해 지면 더 복잡한 아키텍처로 이동하는 것이 훨씬 더 쉬울 것이라고 생각합니다. 적어도 그것이 내가 생각했던 것입니다. :)이 시점에서 당신은 메모리 할당과 관리, 논리 흐름, 디버깅, 테스트 등에 대한 필수적인 지식을 갖게 될 것입니다.


3

디버그 사용에 대한 제안은 재미있는 것입니다. 많은 깔끔한 트릭을 사용할 수 있습니다. 그러나 최신 운영 체제의 경우 16 비트 어셈블리를 배우는 것이 약간 덜 유용 할 수 있습니다. 대신 ntsd.exe를 사용해보십시오. Windows XP에 내장되어 있습니다 (안타깝게도 Server 2003 이상에서 제거됨). 널리 사용되기 때문에 배우기 편리한 도구입니다.

즉, XP의 원래 버전에는 많은 버그가 있습니다. 정말로 그것을 사용하고 싶다면 (또는 동일한 명령 구문과 디버깅 백엔드를 가진 본질적으로 다른 인터페이스 인 cdb 또는 windbg), 무료 Windows 디버깅 도구 패키지를 설치해야 합니다.

해당 패키지에 포함 된 debugger.chm 파일은 비정상적인 구문을 알아 내려고 할 때 특히 유용합니다.

ntsd의 가장 큰 장점은 가까이있는 모든 XP 시스템에서 팝업하여 조립하거나 분해하는 데 사용할 수 있다는 것입니다. / great / X86 어셈블리 학습 도구를 만듭니다. 예를 들어 (dos 프롬프트에서 인라인이므로 cdb 사용, 그렇지 않으면 동일합니다) :

(기호 오류는 관련이 없기 때문에 건너 뛰었습니다. 또한이 서식이 작동하기를 바랍니다. 이것이 제 첫 게시물입니다)

C:\Documents and Settings\User>cdb calc

Microsoft (R) Windows Debugger Version 6.10.0003.233 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: calc
Symbol search path is: *** Invalid ***
Executable search path is:
ModLoad: 01000000 0101f000   calc.exe
ModLoad: 7c900000 7c9b2000   ntdll.dll
ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 7c9c0000 7d1d7000   C:\WINDOWS\system32\SHELL32.dll
ModLoad: 77dd0000 77e6b000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000   C:\WINDOWS\system32\Secur32.dll
ModLoad: 77f10000 77f59000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 7e410000 7e4a1000   C:\WINDOWS\system32\USER32.dll
ModLoad: 77c10000 77c68000   C:\WINDOWS\system32\msvcrt.dll
ModLoad: 77f60000 77fd6000   C:\WINDOWS\system32\SHLWAPI.dll
(f2c.208): Break instruction exception - code 80000003 (first chance)
eax=001a1eb4 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c90120e esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!DbgBreakPoint:
7c90120e cc              int     3
0:000> r eax
eax=001a1eb4
0:000> r eax=0
0:000> a eip
7c90120e add eax,0x100
7c901213
0:000> u eip
ntdll!DbgBreakPoint:
7c90120e 0500010000      add     eax,100h
7c901213 c3              ret
7c901214 8bff            mov     edi,edi
7c901216 8b442404        mov     eax,dword ptr [esp+4]
7c90121a cc              int     3
7c90121b c20400          ret     4
ntdll!NtCurrentTeb:
7c90121e 64a118000000    mov     eax,dword ptr fs:[00000018h]
7c901224 c3              ret
0:000> t
eax=00000100 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c901213 esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
ntdll!DbgUserBreakPoint+0x1:
7c901213 c3              ret
0:000>`

또한-IDA를 사용하는 동안 Chris Eagle의 IDA Pro Book을 확인하십시오 (StackOverflow가 첫 번째 게시물에 대해 두 개 이상의 링크를 게시하는 것을 원하지 않기 때문에 연결 해제 됨). 거기에 가장 좋은 참조가 있습니다.


1
크리스 이글의 책에 +1. ) 꼭 r00t의 Sk3wl 거기에 사랑을 좀 넣어
mrduclaw

3

저는 최근에 컴퓨터 시스템 수업을 들었습니다. 주제 중 하나는 하드웨어와 통신하는 도구로서의 어셈블리였습니다.

나에게 어셈블리에 대한 지식은 컴퓨터 시스템이 어떻게 작동하는지에 대한 세부 사항을 이해하지 않았다면 완전하지 않았을 것입니다. 이를 이해하면 한 프로세서 아키텍처에서 어셈블리 명령이 훌륭하지만 다른 아키텍처에서는 끔찍한 이유에 대한 새로운 이해를 얻을 수 있습니다.

이것을 감안할 때 나는 내 수업 교과서를 추천하는 경향이 있습니다.

컴퓨터 시스템 : 프로그래머의 관점 .

컴퓨터 시스템 : 프로그래머의 관점
(출처 : cmu.edu )

x86 어셈블리를 다루지 만 책은 그보다 훨씬 더 광범위합니다. 프로세서 파이프 라이닝 및 캐시로서의 메모리, 가상 메모리 시스템 등을 다룹니다. 이 모든 것이 주어진 기능에 맞게 어셈블리를 최적화하는 방법에 영향을 줄 수 있습니다.


2

디스어셈블러에 의해 출력되고 어셈블러에 의해 이해되는 (입력으로 사용될 수 있음) ASCII 형식의 opcode 니모닉 (및 해당 매개 변수)을 배우고 싶습니다.

모든 어셈블러 (예 : MASM)가 가능합니다.

그리고 / 또는 그것에 관한 책을 읽는 것이 더 나을 수도 있습니다 (그래서 추천 된 책이 있었는데 어느 것이 기억 나지 않습니다).


2

Windows에서 다른 개발 작업을하고 있습니까? 어떤 IDE에서? VS 인 경우 분해 된 코드를 읽기 위해 추가 IDE가 필요하지 않습니다. 앱을 디버그 (또는 외부 앱에 연결) 한 다음 분해 창 을 엽니 다 (기본 설정에서 Alt + 8). 일반 코드를 통해 수행하는 것처럼 메모리 / 레지스터를 단계별로 살펴 봅니다. 레지스터 창을 열어 둘 수도 있습니다 (기본적으로 Alt + 5).

인텔은 기본 아키텍처 (레지스터, 프로세서 장치 등)에 대한 조사와 전체 지침 참조를 모두 제공하는 무료 설명서 를 제공합니다. 아키텍처가 성숙 해지고 복잡 해짐에 따라 '기본 아키텍처'매뉴얼의 가독성이 점점 낮아집니다. 이전 버전을 손에 넣을 수 있다면 시작하기 더 좋은 곳이있을 것입니다 (P3 매뉴얼도 동일한 기본 실행 환경을 더 잘 설명 합니다).

책에 투자하고 싶다면 여기 에 좋은 소개 글이 있습니다. 아마존에서 'x86'을 검색하면 다른 많은 정보를 얻을 수 있습니다. 여기 에서 다른 질문에서 몇 가지 다른 방향을 얻을 수 있습니다 .

마지막으로, 당신은에서 상당히 혜택을받을 수 읽기 일부 로우 - 레벨의 블로그. 이 바이트 크기 정보 비트는 개인적으로 가장 잘 작동합니다.


2

이것이 반드시 효율적인 코드 작성에 도움이되는 것은 아닙니다!

i86 연산 코드는 Windows 및 Linux 용으로 실행 가능한 바이너리와 코드의 양이 많기 때문에 지속되는 "레거시"형식입니다.

그것은 라틴어로 쓰는 오래된 학자들과 약간 비슷합니다. 갈릴레오와 같은 이탈리아어 사용자는 라틴어로 글을 쓰고 그의 논문은 코페르니쿠스와 같은 폴란드 사용자가 이해할 수 있습니다. 이것은 niether가 라틴어를 특히 잘 했음에도 불구하고 여전히 가장 효과적인 의사 소통 방법이며 라틴어는 수학적 아이디어를 표현하는 쓰레기 언어입니다.

따라서 컴파일러는 기본적으로 x86 코드를 생성하고, 최신 칩은 상위 Op 코드를 읽고 순서가 변경된 실행, 예측 실행, 파이프 라이닝 등을 사용하여 보이는 것을 병렬 위험 명령으로 변환하고 프로세서의 32 또는 64 레지스터를 최대한 활용합니다. 실제로 있습니다 (x86 지침에서 볼 수있는 한심한 8과는 대조적입니다.)

이제 모든 최적화 컴파일러는 이것이 실제로 일어나는 일임을 알고 있으므로 칩이 효율적으로 최적화 할 수 있음을 알고있는 OP 코드 시퀀스를 코딩합니다.이 시퀀스 중 일부는 1990 년경 .asm 프로그래머에게 비효율적으로 보일지라도.

어느 시점에서 당신은 컴파일러 작성자가 수만 년의 노력을 기울인 결과, 보상을 받았다는 사실을 받아 들여야하며, 신뢰해야합니다.

보다 효율적인 런타임을 얻는 가장 간단하고 쉬운 방법은 인텔 C / C ++ 컴파일러를 구입하는 것입니다. 그들은 효율적인 컴파일러를위한 틈새 시장을 가지고 있으며, 내부에서 일어나는 일에 대해 칩 설계자에게 물어볼 수 있다는 장점이 있습니다.


귀하의 이야기는 CISC 프로세서가 내부적으로 RISC 프로세서가되었음을 암시합니다. 내가 오해했을 수도 있지만 이것은 사실이 아닙니다. 그리고 한심한 8? 최신 프로세서 (예 : 1999 년 이후)에는 10gpr : EAX-EFLAGS, 80 비트 FP0-FP7, 64 비트 MMX0-MMX7, 128 비트 XMM0-XMM7, 세그먼트 : CS-GS, 특수 기능 : CR0-CR4 , DR0-DR7, TR3-TR7, GDTR, IDTR, LDTR, MSR 및 x86-64에서도 R8-R15. 이들 모두가 ring-3에서 액세스 할 수있는 것은 아니지만 대부분은 최근 (2006 년 이후) GCC / VC ++ 컴파일러에서 사용됩니다. "불쌍한 8"보다 조금 더;).
Abel

2

원하는 작업을 수행하기 위해 방금 Intel Instruction Set Reference (내가 사용한 정확한 것은 아니지만 충분 해 보임)와 Visual Studio에서 작성한 몇 가지 간단한 프로그램을 가져 와서 IDAPro / Windbg에 던지기 시작했습니다. . 내가 내 프로그램을 능가 했을 때 crackmes 의 소프트웨어 가 도움이되었다.

Windows에서 프로그램이 실행되는 방식에 대한 기본적인 이해가 있다고 가정합니다. 그러나 실제로 어셈블리를 읽는 경우에는 학습해야 할 지침과 해당 지침의 몇 가지 맛만 있습니다 (예 : 점프 지침이 있고 jump에는 jump-if-equal, jump-if-ecx-is-zero와 같은 몇 가지 맛이 있습니다. 등). 기본 지침을 배우면 프로그램 실행의 요점을 얻는 것은 매우 간단합니다. IDA의 그래프보기는 도움이되며 Windbg로 프로그램을 추적하는 경우 확실하지 않은 경우 지침이 수행하는 작업을 파악하는 것은 매우 간단합니다.

그런 식으로 플레이 한 후 Hacker Disassembly Uncovered를 구입했습니다 . 일반적으로 저는 제목에 "Hacker"라는 단어가 포함 된 책에서 멀리 떨어져 있지만 컴파일 된 코드가 어떻게 분해되어 보이는지에 대해이 책이 깊이있는 방식을 정말 좋아했습니다. 그는 또한 컴파일러 최적화와 흥미로운 몇 가지 효율성에 대해서도 설명합니다.

그것은 모두 당신이 프로그램을 얼마나 깊이 이해할 수 있는지에 달려 있습니다. 취약성을 찾는 대상을 리버스 엔지니어링하거나, 익스플로잇 코드를 작성하거나, 압축 된 멀웨어의 기능을 분석하는 경우, 실제로 작업을 진행하기 위해 더 많은 램프 업 시간이 필요합니다 (특히 고급 멀웨어의 경우) ). 반면에 좋아하는 비디오 게임에서 캐릭터의 레벨 만 변경하고 싶다면 비교적 짧은 시간에 잘해야합니다.


1

표준 교육 어셈블리 언어 중 하나는 MIPS입니다. MIPS 시뮬레이터 (spim)와 다양한 교재를 얻을 수 있습니다.

개인적으로 저는 팬이 아닙니다. 나는 IA32를 좋아한다.


MIPS가 좋습니다. 68000도 마찬가지이며 68000을 배우면 MAME에서 실행되는 바이너리를 작성할 수 있습니다. :-)
Nosredna

1

제가 개인적으로 가장 좋아하는 것은 NASM입니다. 대부분 다중 플랫폼이기 때문에 MMX, SSE, 64 비트 ...

저는 gcc로 간단한 C 소스 파일을 컴파일하고 gcc 형식에서 NASM 형식으로 어셈블러 명령어를 "트랜스 코딩"하기 시작했습니다. 그런 다음 코드의 작은 부분을 변경하고 그로 인한 성능 향상을 확인할 수 있습니다.

NASM 문서는 정말 완전해서 책이나 다른 출처에서 정보를 검색 할 필요가 없었습니다.




0

실제로 목표에 도달하려면 현재 사용중인 IDE에서 시작하는 것이 좋습니다. 일반적으로 디스어셈블러 창이므로 코드를 한 단계 씩 실행할 수 있습니다. 일반적으로 레지스터를보고 메모리 영역을 살펴볼 수있는 일종의보기가 있습니다.

최적화되지 않은 c / c ++ 코드를 검사하면 컴파일러가 소스에 대해 생성하는 코드 종류에 대한 링크를 구축하는 데 도움이됩니다. 일부 컴파일러에는 코드에 기계 명령어를 삽입 할 수있는 일종의 ASM 예약어가 있습니다.

제 조언은 잠시 동안 그런 종류의 도구를 가지고 놀다가 발을 적시고 나서 올라가는 것입니다. 하위? 어떤 플랫폼에서 실행 중인지 어셈블러 코드를 직접 작성합니다.

많은 훌륭한 도구가 있지만 처음에는 가파른 학습 곡선을 피하기 위해 더 재미있을 수 있습니다.


0

마이크로 컨트롤러 개발 키트 (Motorola HC12)와 두꺼운 데이터 시트를 사용하여 어셈블리를 배웠습니다.


0

주제에서 벗어난 것은 알고 있지만, 당신은 Windows 프로그래머이기 때문에 MSIL을 배우는 데 시간을 더 적절하고 /하거나 더 잘 사용할 수 있다고 생각합니다. 아니요, 어셈블리는 아니지만이 .NET 시대에 더 관련성이있을 것입니다.


0

어셈블리를 아는 것은 디버깅에 유용 할 수 있지만 코드를 최적화하기 위해 어셈블리를 사용하는 것에 대해 너무 흥분하지 않을 것입니다. 현대 컴파일러는 일반적으로 오늘날 인간을 최적화하는 데 훨씬 더 좋습니다.


흠. 여전히 약간의 추가 코딩 어셈블리를 직접 작성할 수 있지만 컴파일러를 능가하는 데는 예전보다 더 많은 작업이 필요합니다.
Nosredna 09.09.09

0

xorpd x86 어셈블리 비디오 과정을 확인할 수 있습니다 . (내가 썼어). 코스 자체는 유료이지만 연습은 github에서 오픈 소스입니다. 프로그래밍 경험이 있다면 연습만으로 작업하고 모든 것을 이해할 수 있어야한다고 생각합니다.

코드는 Windows 플랫폼 용이며 Fasm 어셈블러를 사용하여 작성되었습니다 . 코스와 연습 문제에는 고수준 구조가 포함되어 있지 않지만, 원한다면 Fasm을 사용하여 매우 복잡한 매크로를 만들 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.