어셈블리어를 배우는 것이 도움될까요?
현재 고등학교 2학년입니다. 프로그래밍에 관심이 많아 파이썬, c++과 html 관련 언어들을 배웠습니다. 프로그래밍을 시작하게 된 계기는 옳지는 못하지만 게임 핵을 직접 만들어보고 싶은 마음에서 시작했습니다. c++은, 게임에서 기초적인 수준의 리버싱은 가능하고, 얻어낸 주소값을 이용해 값을 수정하는 핵을 만드는 등 기초적인 프로그래밍이 가능합니다. 파이썬은 실생활에서 쓸수있는 크롤러, 자바스크립트 연계 등까지 가능하고 이를 위해 html 관련 웹사이트에 대한 지식을 쌓았습니다.
제 원래 목표인 게임 핵과 리버스 엔지니어링을 하기 위해서는 어셈블리어를 배우는 것이 불가피하다고 들었습니다.
정말 어셈블리어를 지금 배우는 것이 맞을까요? 나중에 어셈블리어를 쓸 상황이 많을까요?
긴 질문 읽어주셔서 감사합니다.
우선 게임 핵을 개발하시면서도 느끼셨겠지만 리버싱 없이는 핵을 만들 수 없다고 생각합니다.
게임 핵을 개발한다는 것은 게임을 리버스 엔지니어링으로 분석하고 게임을 원하는 방향으로 변경했다는 뜻인데
따라서 리버스 엔지니어링을 하기 위해서는 당연히 어셈블리어를 아는게 필수적입니다.
지금 배우는 것이 맞는지 물어보셨는데, 원하는 목표가 게임 핵 개발이나 리버싱이시라면
미루실 필요 없이 공부하시는게 맞다고 생각합니다
다만 리버싱을 그저 외우는 방식으로 하면 흥미가 쉽게 떨어지기 때문에
공부하면서 차근차근 알아가는게 흥미를 붙이기도
이후 활용하는데도 보다 좋을 것이라고 생각합니다
모든지 배워두면 좋은 것입니다. 나중에 쓰질 않더라도 어셈블리를 사용하면서 배웠던 메모리 접근이나 저장과 레지스터 연산과같은 로직은 CPU instruction과 ALU 연산에 대한 기본적인 실행 과정을 익히시게 될꺼에요.
하드웨어를 이해하고 프로그래밍하는 것과 그냥 프로그래밍하는 것은 천지 차이입니다. 모든 프로그래밍이 빵빵한 CPU와 메모리가 있는 컴퓨터에서만 하는게 아니라, 굉장히 열악한 CPU와 메모리를 가지고 있는 임베디드라는 장비에서도 프로그래밍 할 수 있습니다. 이럴때 하드웨어를 이해하고 프로그래밍하는 것은 엄청난 메리트입니다.
핵이나 리버스엔지니어링을 하시려면 해당 구조언어, 자료구조, 컴파일러, 어셈블리어 등에 지식이 있으셔야되는게 맞습니다.
다만 어셈블리어는 극한의 성능 혹은 완전 기본단계에서부터의 리버스 엔지니어링이 아닌 경우 그렇게 사용처가 많지 않습니다.
이미 간단한 게임핵을 제조해봐서 아시겠지만.... 리버스 자체를 본인이 처음부터 하지않는이상 어셈블리어를 매우 자주 쓸 일은 보통 없습니다.
다만 기본적으로 어느정도 다룰줄은 아셔야하고 잘 다뤄서 손해볼건 없습니다.
현재 학생이신 경우 어셈블리어를 공부하시는것보다는 관련 학과(정보보안)등에 진학하신 후 학과 커리큘럼 잘 따라가시면서 추가적으로 해당 과목에 대한 이해가 필요하다고 느껴지실때 진입하셔도 절대 늦지 않습니다.
어셈블리어는 정말 하드웨어를 설계하거나 명령어를 새로 만들지 않는한 배울 필요는 없다고 생각이 듭니다.
게임핵을 만드는 방법은 리버스 엔지니어링이 좀더 많이 필요하지 않을까 합니다.
저는 롤플레잉게임 같은거 할 때 특정 값을 찾아서 그값을 수정해서 게임을 쉽게 깬적이 있습니다.
그때 여러가지 방법을 찾았을때 메모리에서 수정하고자 하는 기능의 값을 찾고 그값을 조작 하는 것으로 해보았습니다
이런것을 봤을때는 메모리에 대한 접근 방법과 어떤 값이 어떻게 변경될때 어떠한 부분이 변경되는지 이런 부분을 찾는 툴을 개발해 보는게 어떻까 합니다.
보안에 관심이 많으시군요.
결론부터 말씀드리면 바이너리 리버스엔지니어링은 어셈블리가 기본입니다. 기초적인 수준의 리버싱을 하실 줄 안다고 하시니 어느정도 어셈블리를 보셨을 것이라 기대됩니다.
어셈블리 명령어는 자주 사용되는 것이 많지 않습니다. 전문가라도 잘 알고 있는 어셈블리 명령어는 100개도 안됩니다. 다만 어셈블리 명령어가 단순 명령어 하나로 의미하는 바가 크지 않습니다. 여러줄의 어셈블리 명령어가 조합되어야 하나의 기능이 됩니다.
중요한 것은 리버싱이라는 말 자체가 의미하는 바 대로 어셈블리 코드 자체를 이해하는 것보다는 원래의 코드(컴파일 이전)의 코드로 얼마나 정확히 복원하느냐 입니다. 컴파일러를 잘 생각해보면, 컴파일러는 고수준 언어의 코드를 특정 어셈블리 코드 세트로 변환을 시킵니다. 즉, 변수선언, for문, if문, 함수호출 등 고수준 프로그래밍 언어의 기능들이 특정한 어셈블리 코드로 변환됩니다. 그리고 컴파일러마다 그 패턴이 동일합니다.(대부분의 컴파일러가 거의 비슷합니다.) 이 패턴만 알고 있다면 역으로 어셈블리 코드세트의 패턴을 보고 변수선언인지, 함수호출인지, for문인지 뭘 하는 것인지 쉽게 유추할 수 있습니다. 잘 하는 리버서는 이 패턴을 아주 다양하게 알고 있는 것에 불과 합니다.
다시 한번 결론을 말씀드리자만 리버싱은 어셈블리 언어에 익숙해야 합니다. 하지만 어셈블리 언어 자체가 중요한 것은 아니고 어셈블리 코드로 변환되기 전에 어떤 코드로 부터 나왔는 지 파악하는 것이 중요합니다. 즉, 고수준의 언어에서 어떤 식으로 프로그래밍을 하는 지 먼저 이해해야 이것이 어떤 어셈블리 코드세트로 변환되는 지 패턴을 알 수 있기 때문에 고수준의 언어를 먼저 잘 익히시고, 이것들이 어셈블리 코드로 어떻게 컴파일 되는 지 연구해보시기를 추천드립니다.