0

ターゲット アプリケーションが文字列を連結するために memcpy() 関数を使用し、どの文字列が作成されているかを調べたいので、C で memcpy() 関数を挿入しています。コードは次のとおりです。

void * my_memcpy ( void * destination, const void * source, size_t num )
{
    void *ret = memcpy(destination, source, num);
    // printf ("[MEMCPY] = %s \n", ret);
    return ret;
}

関数は正常に呼び出されますが、最初のパラメーターは何でもかまいません。結果が文字列または配列の場合にのみトレースしたいのです。配列か文字列かを尋ねる必要があります。私はこれが簡単にできないことを知っています.RETが何を指しているのかを知る方法はありますか?

私は MACOSX の下で作業しており、DYLD を介在させています。

どうもありがとうございました。

4

4 に答える 4

2

Asvoid*は未加工のメモリ ブロックを表すため、そこにある実際のデータを特定する方法はありません。

ただし、すべての操作で「文字列のような」メモリ ダンプを作成し、結果の出力に何らかの「出力上限」を与えることができます。

これは、次の方法で実装できます。

const size_t kUpperLimit = 32;

void output_memory_dump(void* memory) {
   std::cout.write(reinterpret_cast<char*>(memory), kUpperLimit);
}

非文字列のようなデータの場合、出力はほとんど解釈できませんが、それ以外の場合は、探していたものを取得できます。

reinterpret_cast<void*>(memory)すべてのシンボルを反復してチェックするなど、推測ベースのアプローチを適用することもできますis_alphanumeric && is_spaceが、このアプローチはあまり安定していないようです (実際に何が含まれているかは誰にもわかりませんvoid*... )。

とにかく、いくつかの状況では問題ないかもしれません。

于 2010-09-30T17:47:09.610 に答える
1

最初に、コピーされたメモリにいくつかのヒューリスティックを適用し、それに基づいて印刷するかどうかを決定できます。

static int maybe_string(const void *data, size_t n) {
  const unsigned char *p;
  size_t i;

  p = data;
  for (i = 0; i < n; i++) {
    int c = p[i];
    if (c == '\n' || c == '\r' || c == '\t')
      continue;
    if (1 <= c && c < 32)
      return 0; /* unusual ASCII control character */
    if (c == '\0' && i > 5)
      return 1; /* null-terminated and more than a few characters long */
  }

  return 0; /* not null-terminated, so it isn't a string */
}

このヒューリスティックは完全ではありません。たとえば、次のパターンでは失敗します。

const char *str = "hello, world";
size_t len = strlen(str);
char *buf = malloc(1024);
memcpy(buf, str, len);
buf[len] = '\0';

それもキャッチしたい場合は、上記の関数を変更する必要があります。

于 2010-09-30T17:47:47.097 に答える
0

いいえ、void型のポインタからこれを理解することはできません。さらに、送信元または宛先のサイズがわからないため、ヒューリスティックなアプローチは機能しません。他の理由でも機能しません。たとえば、が指すメモリ領域に格納されているバイナリデータは、void*実際には最後に0バイトになる可能性がありますが、それが文字列であることを意味するわけではありません。

于 2010-09-30T17:55:55.207 に答える
0

ret宛先ポインターと同じです。ただし、配列または文字列に関する詳細情報 (たとえば、文字列が特定の長さであり、null で終了しているなど) を把握していない限り、それが配列か文字列かを判断することはできません。

于 2010-09-30T17:45:01.987 に答える