답변1
aptitude
시스템 C 라이브러리의 POSIX/API를 사용한 regcomp()
정규식 일치regexec()
수신 전화regcomp()
그리고REG_ICASE | REG_EXTENDED
배너이므로 본질적으로 1 과 동일한 결과를 얻게 되며 grep -iE
대소문자 구분을 끄는 기능이 기본적으로 지원되지 않습니다.
이제 약간의 노력만 기울인다면 할 수 있는 일이 아직 남아 있습니다. 결국 이 소프트웨어는 모두 무료이며 오픈 소스 소프트웨어이므로 수행할 수 있는 작업에는 제한이 없습니다.
예를 들어, 플래그를 제거하는 트릭을 사용하여 regcomp()
libc 함수 호출을 가로챌 수 있습니다.LD_PRELOAD
REG_ICASE
$ cat case-sensitive.c
#define _GNU_SOURCE
#include <dlfcn.h>
#include <regex.h>
int regcomp (regex_t *_Restrict_ __preg,
const char *_Restrict_ __pattern,
int __cflags)
{
static int (*orig) (regex_t *_Restrict_ __preg,
const char *_Restrict_ __pattern,
int __cflags) = 0;
if (!orig)
orig = (int (*) (regex_t *_Restrict_ __preg,
const char *_Restrict_ __pattern,
int __cflags)) dlsym (RTLD_NEXT, "regcomp");
return (*orig)(__preg, __pattern, __cflags & ~REG_ICASE);
}
$ gcc -fPIC -shared -o case-sensitive.so case-sensitive.c
zsh
그런 다음 설명에 다음이 포함된 패키지를 검색하여 효과를 확인할 수 있습니다 Zsh is a UNIX command interpreter
.
$ apt-cache show zsh
Package: zsh
[...]
Description-en_GB: shell with lots of features
Zsh is a UNIX command interpreter (shell) usable as an interactive login
[...]
$ aptitude search -F %p '~n "^zsh$" ~d "Zsh .* unix"'
zsh
zsh:i386
$ LD_PRELOAD=$PWD/case-sensitive.so aptitude search -F %p '~n "^zsh$" ~d "Zsh .* unix"'
$ LD_PRELOAD=$PWD/case-sensitive.so aptitude search -F %p '~n "^zsh$" ~d "Zsh .* UNIX"'
zsh
zsh:i386
case-insensive.so
libc의 regcomp()
/ API를 사용하면 무엇이든 사용할 수 있습니다 regexec()
. 디버거 등과 일치하는 특정 정규식에 대해 ltrace
작업이 수행되었는지 알 수 있습니다.
int regcomp(addr, string, bitvec(int));
에 추가 ~/.ltrace.conf
:
$ ltrace -e regcomp aptitude search ZZZ
[...]
libapt-pkg.so.6.0->regcomp(0x55d9a6f1ad60, "^linux-image-[a-z0-9]*-[a-z0-9]*"..., <0-1,3>) = 0
libapt-pkg.so.6.0->regcomp(0x55d9a6f2f060, "^linux-.*-6\\.6\\.15-amd64$|^linux"..., <0-1,3>) = 0
aptitude->regcomp(0x55d9a6f1cb10, "linux-image-.*", <0-1>) = 0
aptitude->regcomp(0x55d9a6f62980, "linux-image-.*", <0-1,3>) = 0
libapt-pkg.so.6.0->regcomp(0x55d9a6ed08c0, "^linux-.*-.*$|^kfreebsd-.*-.*$|^"..., <0-1,3>) = 0
aptitude->regcomp(0x55d9a6f60270, "ZZZ", <0-1>) = 0
aptitude->regcomp(0x55d9a6f5e830, "ZZZ", <0-1,3>) = 0
p elpa-zzz-to-char - fancy version of `zap-to-char' command
p python3-zzzeeksphinx - Zzzeek's Sphinx layout and utilities
(여기서 플래그는 비트 벡터로 표시되며, 여기서 0은 REG_EXTENDED
1 입니다 REG_ICASE
.)
일부 적절한 라이브러리의 aptitude
간접 호출 로 인해 regcomp()
종료가 REG_ICASE
문제를 일으킬 수 있는 방법을 이해하십시오.
또한 search
. aptitude
특히, 이 $LD_PRELOAD
변수는 실행하는 모든 명령에 전달되므로 원하지 않습니다.설치하다모든 패키지는 aptitude
이러한 환경에서 시작됩니다. 이와 관련하여 공유 객체 파일을 미리 로드하는 것이 더 나을 것입니다 . /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 --preload "$PWD/case-sensitive.so" /usr/bin/aptitude search...
이렇게 하면 .aptitude
GNU는 ed
libc의 POSIX 정규식 API도 사용합니다.
$ echo /Debian/I | ltrace -e regcomp ed -sE /etc/issue
ed->regcomp(0x5653bd71f520, "Debian", <0-1>) = 0
Debian GNU/Linux trixie/sid \n \l
+++ exited (status 0) +++
$ echo /Debian/I | LD_PRELOAD=$PWD/case-sensitive.so ed -sE /etc/issue
Debian GNU/Linux trixie/sid \n \l
$ echo /debian/I | LD_PRELOAD=$PWD/case-sensitive.so ed -sE /etc/issue
?
표준 ERE에는 대소문자 구분 안 함을 켜거나 끄는 연산자가 없지만 Perl 정규식을 (?i)
(?-i)
다른 도구에 가져오도록 설계된 라이브러리인 PCRE2와 마찬가지로 Perl 정규식을 사용할 수 있습니다. Perl 정규식은 대부분 ERE와 호환됩니다.
PCRE2는 라이브러리에서 regcomp()
/standard API를 지원합니다.regexec()
libpcre-posix
따라서 aptitude
표준 ERE 대신 PCRE2를 사용하도록 수정하는 것이 상대적으로 쉽습니다.
예를 들어 PoC로서 내가 해야 할 일은 다음과 같습니다.
$ sudo apt build-dep aptitude
$ apt source aptitude
$ cd aptitude*(/)
다음과 같이 하나를 만듭니다 src/regex.h
.
$ cat src/regex.h
#ifndef _REGEX_H
#define _REGEX_H 1
#include <pcre2posix.h>
#endif
그런 다음 빌드하십시오.
dpkg-buildpackage -b -j5
누락으로 인해 실패했습니다 -lpcre2-posix
. 내가 해야 할 일은 다음과 같습니다.
make -C build MAYBE_LIBGTK=-lpcre2-posix
(이것은 MAYBE_LIBGTK
파일 수정을 방지하기 위해 링크 단계에서 참조되는 설정되지 않은 make 변수를 사용합니다.)
그런 다음 이제 정규식을 aptitude
사용하는 것이 있습니다 PCRE2
.
$ build/src/aptitude search -F %p '~n "^zsh$" ~d "Zsh .* unix"'
zsh
zsh:i386
$ build/src/aptitude search -F %p '~n "^zsh$" ~d "(?-i)Zsh .* unix"'
$ build/src/aptitude search -F %p '~n "^zsh$" ~d "(?-i)Zsh .* UNIX"'
zsh
zsh:i386
1 GNU의 경우 grep
사용되는 정규식 엔진과 API는 버전과 여러 요소에 따라 다르지만 regcomp()
GNU libc를 사용하는 시스템에서도 시스템 libc에서는 /를 사용하지 않을 수 있습니다.regexec()