아핫뉴스실시간 인기검색어
아핫뉴스 화산 이미지
화산 아이콘 11
폰허브 개인정보 유출
아하

생활

생활꿀팁

조용한콜리221
조용한콜리221

리버스엔진어링을 어떻게 하는건가요?

리버스엔지니어링이란거를 어디서 어떻게 해야하는지 잘모르겠어요 어떻게하면 그앱의 코딩을 볼수있는지 리버스엔지리어링을 통해 다른사람들이 만들어놓은 코딩을 보고 저도 만들어보고 싶습니다

    3개의 답변이 있어요!
    • 보랏빛수염고래51
      보랏빛수염고래51

      프로그램을 만드는 과정은 다음과 같습니다.

      프로그래밍 언어로 구현 -> 컴파일 (기계어, 바이너리) -> 바이너리실행

      컴파일은 프로그래밍언어를 컴퓨터가 이해할 수 있는 기계어 즉 0과 1로 된 바이너리로 변환시켜줍니다.

      리버스엔지니어링은 이런 0과 1을 해석해서 프로그래밍언어로 복구하는 것입니다. 상당히 쉽지 않겠죠.

      굉장히 어렵기 때문에 추천드리지 않고, 그냥 오픈소스를 보시는걸 추천드려요.

      https://github.com/ 에서 프로젝트검색을 통해 소스코드 확인해 보실 수 있습니다.

    • 리버스 엔지니어링을 이해하시기 전에 프로그래밍의 아주 간단한 역사를 들어보시면 리버스 엔지니어링이 귀에 쏙 들어오실 겁니다.

      원래 컴퓨터는 기계어라고 하는 숫자로 이루어진 명령어만 읽고 해석할 수 있습니다. 숫자로만 이루어져 있기 때문에 그 많은 명령어들을 외우고 명령어를 작성하기가 너무 힘들었습니다. 이 기계어를 좀 더 쉽게 다루기 위해 어셈블리어가 만들어졌습니다.

      어셈블리어는 이 숫자로 이루어진 기계어를 문자로된 명령어로 표시할 수 있도록 고안된 언어입니다. 예를 들어 13이라는 값을 eax라는 cpu의 공간(레지스터)에 저장하라는 명령이 기계어로는 853413 라고 한다면 어셈블리어로는 mov 13 eax 이라고 표현하면 됩니다. mov 는 move의 약자이고 13은 저장할 수 eax는 레지스터 이름입니다. 기계어에 비해 훨씬 직관적으로 보입니다. 어셈블리어를 통해 이런식으로 있으면 한결 편하게 컴퓨터에게 명령어를 전달할 수 있을 것 같습니다. 하지만 어셈블리어를 제대로 다룰려면 cpu의 레지스터들과 하드웨어를 다루는 여러 어셈블리 명령어들을 이해해야 할 필요가 있습니다. 그리고 명령어가 하드웨어를 동작시키는 아주 기본단위로 이루어져 코드의 양이 어마무시하게 많았습니다.

      어셈블리어를 좀 하다보니 개발자들이 구현하고자 하는 어떠한 기능들이 특정한 패턴을 가지고 있다는 것을 알게되었습니다. 그 패턴들을 어셈블리어로 간소화하는 데에 한계가 있었고 더 편리하게 패턴을 구현하는 언어를 개발했습니다. 그 중 하나가 c언어입니다. 함수라는 문법을 통해서 입력값과 출력값을 갖는 명령어 세트를 표현할 수 있게 되었고, 메모리 공간을 할당하고 값을 저장하는 것도 변수라는 것을 통해서 좀더 직관적인 표현으로 문법을 구성했습니다. 이 외에 반복문, 비교문 등 여러 문법들이 이 패턴들이라고 생각하시면 됩니다. 추가로 c언어에서도 자주 사용될 만한 기능들은 내장함수 형태로 미리 만들어 두어 아주 간편하게 호출할 수 있게 제공합니다.

      c언어 명령어 1개는 여러개의 어셈블리 명령어를 축약한 형태입니다. 예를 들어 int i = 3; 이라는 실행문은 메모리 공간 할당요청(1)과 메모리에 데이터 저장(2) 이라는 어셈블리 명령어로 변환이 됩니다. 우리는 메모리의 복잡한 권한과 cpu의 다양한 저장공간, 기능 들에 대해 잘 알지 못해도 좀 더 직관직인 c 언어의 명령어(문법)들을 이용하면 나중에 컴파일이라는 과정을 통해서 기계어로 변환할 수 있습니다.

      그럼 다시 리버스엔지니어링으로 되돌아오겠습니다. c언어의 실행문 1개는 1개 이상의 기계어(기계어는 어셈블리어로 1:1변환 가능합니다.)로 변환됩니다. c언어의 모든 실행문들이 어떤 기계어로 변환이 된다는 것을 알고 있다면 바이너리 실행파일의 기계어의 순서를 보고 원래의 c 언어로 역변환이 가능합니다. 이것을 리버스엔지니어링이라고 합니다. 실제로는 기계어가 어셈블리어로 1:1변환이 가능하기 때문에 어셈블리 명령어를 보고 c언어로 추정을 하곤 합니다. 이것이 리버스 엔지니어링의 기본입니다. 물론 리버싱은 어셈블리어를 이해해야 하기 때문에 여기에 cpu 레지스터에 대한 지식과 메모리의 섹션과 권한 그리고 운영체제에 대한 이해도가 필요합니다.

      리버스엔지니어링을 공부하신다면 c언어와 같은 고수준 언어를 통해 프로그램을 개발하여 컴파일된 바이너리 코드를 디버거 등으로 변환된 어셈블리어를 보며 컴파일되는 패턴을 익혀나가신다면 훌륭한 초보 리버서가 되실 수 있습니다.

    • 다른사람이 만들어 놓은 코드를 보고 싶다면 github에 올라와 있는 코드를 보는 것이 좋습니다.

      앱의 코드를 디컴파일 하면 완벽하게 똑같은 코드가 나오는 것은 아닙니다.

      최근에는 디컴파일을 방지하는 솔루션들을 회사에서 도입해서 사용하는 경우가 많아 디컴파일이 불가능한 경우도 있습니다.

      apk 디컴파일 검색어로 구글에서 검색해보면 많은 내용들이 있습니다.

      요즘은 웹에 apk를 올리면 디컴파일된 파일을 다운 받을 수 있도록 해줍니다.

      개인적으로 디컴파일을 사용할때는 어떠한 기능을 어떻게 만들었는지 궁굼하면 한번씩 해보기는 합니다.

      정확한 코드보다는 기본제공하는 코드를 사용했는지 아니면 라이브러리를 사용했는지를 보고 그것으로 다시 검색을 하는 편입니다.

      난독화가 되더라도 라이브러리나 안드로이드 기본 컴포넌트들은 난독화를 안하기 때문에 코드를 보고 힌트를 얻는 것이지 거기에 있는 코드를 바로 사용하기는 어렵습니다.