/dev/zero
0x00だけでなく、0x01と0xFFの間のすべてのバイトのソースを取得できるようにビットマスクをどのように追加しますか?
答え1
次のbash
コードは、表示されたバイトで使用するように設定されています。バイナリ。しかし、簡単に変更できます。オカト、少数または16進数単に変更することでカーディナリティ r
2
value8
または個別に設定し、10
それに応じて設定します。 16
b=
r=2; b=01111110
printf -vo '\\%o' "$(($r#$b))"; </dev/zero tr '\0' "$o"
編集する- それを扱う全シリーズバイト値:16進数 00-FF(以下に00-7Fを書き込むときは、シングルバイトUTF-8文字のみを考慮してください。)
たとえば、4バイトのみが必要な場合(16進00-7Fの範囲のUTF-8 'ASCII'専用文字)、パイプで接続できます。頭:... | head -c4
出力(4文字):
~~~~
8ビット形式で出力を表示するには、パイプxxd
(または他の形式)でパイプします。1と0バイトダンプ*):
はい。b=10000000
次にパイプされます。... | head -c4 | xxd -b
0000000: 10000000 10000000 10000000 10000000 ....
答え2
答え3
まあ、もし文字通りこれを達成するには、次のものを使用できます。LD_PRELOADフック。基本的な考え方は、Cライブラリの関数をオーバーライドして、通常の関数の代わりに使用することです。
これは書き直す簡単な例です。読む()この関数は出力バッファを0x42にXORします。
#define _GNU_SOURCE
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <unistd.h>
static int dev_zero_fd = -1;
int open64(const char *pathname, int flags)
{
static int (*true_open64)(const char*, int) = NULL;
if (true_open64 == NULL) {
if ((true_open64 = dlsym(RTLD_NEXT, "open64")) == NULL) {
perror("dlsym");
return -1;
}
}
int ret = true_open64(pathname, flags);
if (strcmp(pathname, "/dev/zero") == 0) {
dev_zero_fd = ret;
}
return ret;
}
ssize_t read(int fd, void *buf, size_t count)
{
static ssize_t (*true_read)(int, void*, size_t) = NULL;
if (true_read == NULL) {
if ((true_read = dlsym(RTLD_NEXT, "read")) == NULL) {
perror("dlsym");
return -1;
}
}
if (fd == dev_zero_fd) {
int i;
ssize_t ret = true_read(fd, buf, count);
for (i = 0; i < ret; i++) {
*((char*)buf + i) ^= 0x42;
}
return ret;
}
return true_read(fd, buf, count);
}
無邪気な実装は、私たちが読み取るすべてのファイルをXOR 0x42として扱うので、望ましくない結果につながる可能性があります。この問題を解決するために私も電話を切った。開いている()/dev/zero に関連付けられたファイル記述子を取得する関数です。それから私達は私達の仕事だけ読む()fd == dev_zero_fd
.
使用法:
$ gcc hook.c -ldl -shared -o hook.so
$ LD_PRELOAD=$(pwd)/hook.so bash #this spawns a hooked shell
$ cat /dev/zero
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
答え4
ビットマスク/ 0バイトXORを試すことは意味がありません。そうではありませんか?バイトを取得してxor
ゼロとして処理することは何もしません。
必要なバイトを提供するループを作成し、それをパイプまたは名前付きパイプの後に置くだけです。これは文字デバイスとほぼ同じように機能します(アイドル状態のときにCPUサイクルが無駄にならない)。
mkfifo pipe
while : ; do echo -n "a"; done > pipe &
スーパー最適化が必要な場合は、次のCコードを使用できます。
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char c = argc == 1+1 ? argv[1][0] : 'y';
char buff[BUFSIZ];
memset(buff, c, BUFSIZ);
for(;;){
write(1, buff, sizeof(buff));
}
}
コンパイルと実行
$ CFLAGS=-O3 make loop
./loop "$the_byte_you_want" > pipe
性能試験:
./loop 1 | pv -a >/dev/null
2.1GB/秒マイコンピュータでは(より少し高速ですcat /dev/zero | pv -a >/dev/null
。