실행 바이너리에서 문자열을 언제 편집 할 수 있습니까?


11

실행 가능한 바이너리가 있습니다. 그것을 호출하자 a.out. 바이너리에 문자열이 포함되어 있음을 알 수 있습니다

$ strings a.out
...
/usr/share/foo
....

문자열 /usr/share/foo을 로 변경해야합니다 /usr/share/bar. 문자열을 sed?로 바꿀 수 있습니까 ?

sed -i 's@/usr/share/foo@/usr/share/bar@' a.out

이것은 안전한 것 같습니다. 문자열의 길이가 동일하지 않은 경우에도 작동합니까?

답변:


17

나는 당신의 버전 sed이 바이너리 클린인지 또는 입력에서 실제로 긴 줄이라고 생각하는 것을 질식 시킬지 모르겠지만, 그러한 문제를 피하고, 문자열을 제자리에서 편집하면 효과가 있습니다. 그것이 있는지 여부를 확인하려면 이전 버전과 새 버전을와 비교하십시오 cmp -l. 두 파일 간의 유일한 세 가지 차이점이 3 바이트인지 여부를 알려 주어야합니다.

컴파일 된 실행 파일에서 문자열을 편집하면 문자열의 길이가 같은 경우 실제로 작동하지만 C에서 문자열이 작동하는 방식으로 인해 문자열을 줄이면 거의 항상 작동합니다. C 문자열에서는 NUL종료 후 모든 것 계산하지 않으므로 NUL이전 종결 자보다 먼저 새로운 종결자를 쓰면 효과적으로 줄을 줄일 수 있습니다.

일반적으로이 핵을 사용하여 문자열을 늘릴 수있는 방법은 없습니다.


다음과 같이 문자열을 단축하는 것은 sed -i 's@longstring@foo@' a.out어떻습니까? 이것은 전체 바이너리를 7 바이트 작게 만듭니다. 바이너리가 손상되지 않습니까?
— Martin Vegter

예, 바이너리를 손상시킵니다. 그렇기 때문에 문자열을 정확히 같은 길이 중 하나로 변환해야하지만 NUL설명 된 것처럼 초기 위치에 종결 자를 설정해야 합니다 (아마도 너무 짧을 수도 있음). 문제는 NUL명령 줄에 바이트를 가질 수 없으므로 sed프로그램을 파일에 넣고로 참조해야한다는 것입니다 -f. 다른 한편으로, 더 안전한 방법 sed은 텍스트 데이터와 함께 작동하도록 설계된 대신 이진 데이터와 함께 작동하도록 설계된 도구를 사용하는 것입니다 .
— Celada

2
좋은 대답입니다. sed는 많은 일을 할 수 있지만 일반적으로 바이너리 편집기가 고안된 것입니다. 큰 이진 파일 내에서 탐색 할 때 사용하기 어려울 수 있지만 항목을 바이트 단위로 변경할 수 있습니다. hexedit바이너리 파일을 검사하거나 변경해야 할 때 사용 합니다. strings -t x file | less편집기로 이동하기 전에 변경하려는 (인쇄 가능한) 문자열의 오프셋을 찾는 데 사용할 수 있습니다 .
— Joe

C 프로그램에 "My name was Mr Robot"이라는 문자열이 있고 'was'를 'is'로 바꾸고 싶다면 패딩 \0을 신중하게 수행해야합니다. is \ 0 Mr Robot "을 입력 한 다음 문자열로 작업을 수행하는 동안 '\ 0'문자는 길이를 실수로 줄이므로 문제가 발생합니다.
— Nehal J Wani

@NehalJWani 아니요,이 경우 문자열의 나머지 부분을 1 바이트 앞으로 이동하여 새롭고 추가로 끝나는 NUL것이 기존에 인접한 끝까지 계속 되도록해야합니다 NUL.
— Celada
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.