주소는 프로그램 이름에 붙은 고정 번호가 아니다
첫 실행에서 찾은 함수 주소를 다음 실행에도 그대로 쓰면 중단점이 잡히지 않거나 다른 영역을 가리킬 수 있습니다. 운영체제는 실행 파일과 라이브러리 등을 매번 같은 위치에 배치하지 않을 수 있습니다. ASLR은 이런 주소 배치의 무작위화와 관련된 보호 기법입니다. 또한 빌드가 바뀌면 모듈 내부에서 함수가 놓인 위치 자체가 달라질 수 있습니다. 주소가 달라졌다는 사실만으로 파일이 변조되었거나 디버거가 오작동했다고 볼 수는 없습니다. 같은 실행의 주소를 비교하는지, 다른 실행이나 다른 빌드의 값을 비교하는지부터 구분해야 합니다.
함수명과 주소 중단점의 수명 차이
함수명으로 지정한 중단점은 디버거가 심볼을 이용해 실제 위치를 찾습니다. 반면 *0x주소 형식은 특정 숫자를 직접 지정하므로 그 숫자가 현재 세션에서 유효한지 사용자가 확인해야 합니다. 심볼이 없는 프로그램에서 주소 중단점은 필요하지만, 메모한 숫자를 그대로 다음 실행에 옮기는 방식은 불안정합니다. DBG Desk의 현재 버전에는 모듈 목록이나 상대 주소를 자동으로 다시 계산하는 UI가 없습니다. 이름 기반 위치를 사용할 수 있는지 먼저 확인하고, 주소로 지정해야 한다면 현재 실행에서 관찰한 명령어와 주변 문맥이 맞는지 다시 확인하세요.
기준 주소와 내부 오프셋을 구별하기
모듈의 기준 주소가 바뀌어도 같은 빌드 안에서 특정 코드의 상대 위치는 비교에 도움이 될 수 있습니다. 다만 이 개념을 모든 종류의 주소에 그대로 적용하면 안 됩니다. 힙 객체나 스택 데이터의 주소는 모듈 코드와 다른 조건으로 배치되고 객체의 생성 순서나 호출 깊이에도 영향을 받습니다. 코드 주소를 기록할 때는 모듈과 빌드 정보, 상대 위치를 함께 적고 데이터 주소를 기록할 때는 어떤 객체의 어느 시점인지 남기세요. 절대 주소 한 줄만 있는 오류 보고서는 다른 실행에서 재현할 단서가 부족합니다. 해당 위치를 찾은 경로도 같이 기록하는 것이 좋습니다.
주소를 고정하기보다 재현 절차를 안정시키기
주소가 매번 바뀌어 불편하다고 보안 기능을 끄는 것을 기본 해결책으로 삼을 필요는 없습니다. 입력과 빌드, 함수명 중단점을 정리하면 주소를 직접 외우지 않고 같은 실행 지점에 도달할 수 있습니다. 처음에는 작은 재현 프로그램에서 함수 진입과 포인터 생성 시점을 정해 관찰해 보세요. 디버깅 조건에서 주소 무작위화가 어떻게 적용되는지는 운영체제와 디버거 설정에 따라 다를 수 있으므로 무조건 매번 바뀐다고 단정해서도 안 됩니다. 중요한 것은 현재 세션에서 확인한 주소만 믿고, 다른 세션과 비교할 때는 주소에 붙는 문맥을 함께 옮기는 습관입니다.
주소 기록에 문맥을 붙이는 예
메모에 0x숫자만 적는 대신 어떤 실행 파일의 어떤 함수 진입 뒤에서 본 주소인지 써 보세요. 심볼이 있다면 함수 이름과 대략적인 내부 위치를 함께 남길 수 있습니다. 같은 주소가 다음 실행에서 안 보이더라도 같은 함수에 다시 정지해 현재 값을 찾으면 비교가 가능합니다. 반대로 함수 내용이 바뀐 새 빌드에서는 이전 오프셋을 자동으로 같은 계산이라 생각하지 마세요. 수정된 명령어와 빌드 정보를 확인해야 합니다. 데이터 포인터라면 할당한 크기와 객체가 생성된 순서도 단서입니다. 숫자 자체보다 그 위치를 다시 찾을 수 있는 절차가 좋은 디버깅 기록을 만듭니다.