LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1230|回复: 13

程序直接访问内存的疑问

[复制链接]
发表于 2006-9-29 16:18:44 | 显示全部楼层 |阅读模式
我在 redhat下
首先用gdb 调试一个小程序,获得argv的地址

  1. [/home/inter/lp/play>]gdb -q test2
  2. (gdb) l
  3. 1       int main(int argc,char**argv,char**env)
  4. 2       {
  5. 3               int i=0;
  6. 4               for(;i<5;i++)
  7. 5                       ;
  8. 6               return 0;
  9. 7       }
  10. (gdb) b2
  11. Undefined command: "b2".  Try "help".
  12. (gdb) b 3
  13. Breakpoint 1 at 0x8048304: file test2.c, line 3.
  14. (gdb) r
  15. Starting program: /home/inter/lp/play/test2

  16. Breakpoint 1, main (argc=1, argv=0xbfffd9e4, env=0xbfffd9ec) at test2.c:3
  17. 3               int i=0;
  18. (gdb) p &argv
  19. $1 = (char ***) 0xbfffd9a4
  20. (gdb) x/40x 0xbfffd9a4
  21. 0xbfffd9a4:     0xbfffd9e4      0xbfffd9ec      0x4001582c      0x00000001
  22. 0xbfffd9b4:     0x08048244      0x00000000      0x08048265      0x080482f4
  23. 0xbfffd9c4:     0x00000001      0xbfffd9e4      0x08048324      0x08048354
  24. 0xbfffd9d4:     0x4000c660      0xbfffd9dc      0x00000000      0x00000001
  25. 0xbfffd9e4:     0xbffff8a2      0x00000000      0xbffff8bc      0xbffff8d5
  26. 0xbfffd9f4:     0xbffff8e9      0xbffff8fa      0xbffff905      0xbffff915
  27. 0xbfffda04:     0xbffff923      0xbffff946      0xbffff973      0xbffff999
  28. 0xbfffda14:     0xbffff9ad      0xbffff9b8      0xbffffb7b      0xbffffc10
  29. 0xbfffda24:     0xbffffc21      0xbffffc36      0xbffffca5      0xbffffcc0
  30. 0xbfffda34:     0xbffffccc      0xbffffce4      0xbffffcf9      0xbffffd14
  31. (gdb) x/s 0xbffff8a2
  32. 0xbffff8a2:      "/home/inter/lp/play/test2"
  33. (gdb)
复制代码

我想通过另一个程序读 0xbffff8a2 这块内存
看看能否取出 home/inter/lp/play/test2

结果是 用gdb调试 还可以打印出一部分内容,而直接运行程序就什么都不打印

  1. [/home/inter/lp/play>]cc -g test16.c -o test16
  2. [/home/inter/lp/play>]gdb test16
  3. GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
  4. Copyright 2003 Free Software Foundation, Inc.
  5. GDB is free software, covered by the GNU General Public License, and you are
  6. welcome to change it and/or distribute copies of it under certain conditions.
  7. Type "show copying" to see the conditions.
  8. There is absolutely no warranty for GDB.  Type "show warranty" for details.
  9. This GDB was configured as "i386-redhat-linux-gnu"...
  10. (gdb) l
  11. 1       int main(int argc,char *argv[])
  12. 2       {
  13. 3               char *p;
  14. 4               p=(char *)0xbffff8a2;
  15. 5               printf("...%s...\n",p);
  16. 6               return 0;
  17. 7       }
  18. (gdb) r
  19. Starting program: /home/inter/lp/play/test16
  20. ...ome/inter/lp/play/test16...

  21. Program exited normally.
  22. (gdb) q
  23. [/home/inter/lp/play>]./test16
  24. ...686...
  25. [/home/inter/lp/play>]

复制代码


搞不明白,还请清楚的人说明一下,谢谢了
是不能直接访问内存还是怎么回事??????
疑惑多多啊
发表于 2006-9-29 16:51:04 | 显示全部楼层
两个程序的 0xbffff8a2 地址是不相干的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-29 17:22:12 | 显示全部楼层
那要怎样才能在另一个程序里面打印出
test2中 0xbffff8a2的东西呢

还请好好说说
回复 支持 反对

使用道具 举报

发表于 2006-9-29 18:26:46 | 显示全部楼层
这个问题我说不清楚,我只是看过以前的一些讨论而已,不过本版有很多大侠都能帮你解答的。
回复 支持 反对

使用道具 举报

发表于 2006-9-29 23:13:50 | 显示全部楼层
也许楼主可以用共享内存或者建立二者都有读写权限的文件或者用 socket 等方式进行数据的共享. 这不是全部可能的方法, 也不一定都正确, 我只是想到什么写什么.

期待大侠的出现
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-30 09:54:42 | 显示全部楼层
我就是希望能够读取内存中的一些东西
我其实是对某一时刻内存中放了什么东西感兴趣,呵呵

哪位大师能讲讲呢

如何明白的访问内存,而不是选一个值乱打印一通
回复 支持 反对

使用道具 举报

发表于 2006-9-30 17:05:14 | 显示全部楼层
每个进程有各自独立的地址空间, 它们一般是互不干涉的. 没有特殊要求不要考虑去访问其它程序的内存
回复 支持 反对

使用道具 举报

发表于 2006-10-1 04:10:57 | 显示全部楼层
如果想完全在userspace的話用LD_PRELOAD讀入一個library,library用constructor attribute bind 一個port,那時候你想做甚麽也可以了。
回复 支持 反对

使用道具 举报

发表于 2006-10-1 08:45:44 | 显示全部楼层
debug.c:

  1. #include <glib.h>

  2. #include <arpa/inet.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/socket.h>
  6. #include <sys/types.h>

  7. void ld_attach() __attribute((constructor));
  8. static gboolean ld_read_cb(GIOChannel *source, GIOCondition cond,
  9.                            gpointer data);
  10. static gboolean ld_conn_cb(GIOChannel *source, GIOCondition cond,
  11.                            gpointer data);
  12. static int ld_create_socket();

  13. static guint source_id = -1;

  14. void
  15. ld_attach()
  16. {
  17.     int fd = ld_create_socket();

  18.     if (fd == -1) {
  19.         return;
  20.     }

  21.     GIOChannel *channel = g_io_channel_unix_new(fd);

  22.     source_id = g_io_add_watch(channel, G_IO_IN | G_IO_HUP, ld_conn_cb, NULL);
  23. }

  24. static gboolean
  25. ld_conn_cb(GIOChannel *channel, GIOCondition cond, gpointer data)
  26. {
  27.     struct sockaddr_in in_addr;
  28.     socklen_t size = -1;

  29.     if (cond == G_IO_IN) {
  30.         int fd = g_io_channel_unix_get_fd(channel);
  31.         int new_fd = -1;

  32.         size = sizeof(in_addr);
  33.         if ((new_fd = accept(fd, (struct sockaddr *)&in_addr, &size)) == -1) {
  34.             perror("accept");
  35.             return TRUE;
  36.         }

  37.         GIOChannel *channel2 = g_io_channel_unix_new(new_fd);
  38.         source_id = g_io_add_watch(channel2, G_IO_IN | G_IO_HUP, ld_read_cb,
  39.                                    NULL);
  40.     }

  41.     return TRUE;
  42. }

  43. static gboolean
  44. ld_read_cb(GIOChannel *channel, GIOCondition cond, gpointer data)
  45. {
  46.     int addr = 0;
  47.     char *line = NULL;

  48.     if (cond == G_IO_IN) {
  49.         while (g_io_channel_read_line(channel, &line, NULL, NULL, NULL) ==
  50.                G_IO_STATUS_NORMAL) {
  51.             if (sscanf(line, "%x\n", &addr) == 1) {
  52.                 char *ptr = GINT_TO_POINTER(addr);
  53.                 int i = 0;

  54.                 printf("Reading address %p: ", ptr);

  55.                 for (i = 0; i < 10 && *ptr; i++, ptr++) {
  56.                     printf("%c", *ptr);
  57.                 }

  58.                 printf("\n");
  59.             }
  60.         }
  61.     } else if (cond == G_IO_ERR || cond == G_IO_HUP) {
  62.         g_io_channel_shutdown(channel, FALSE, NULL);
  63.     }

  64.     return TRUE;
  65. }

  66. static int
  67. ld_create_socket()
  68. {
  69.     int fd = -1;
  70.     struct sockaddr_in addr;

  71.     if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  72.         perror("socket");
  73.         return -1;
  74.     }

  75.     memset(&addr, 0, sizeof(addr));
  76.     addr.sin_family = AF_INET;
  77.     addr.sin_addr.s_addr = INADDR_ANY;
  78.     addr.sin_port = htons(34567);

  79.     if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
  80.         perror("bind");
  81.         return -1;
  82.     }

  83.     if (listen(fd, 0) == -1) {
  84.         perror("listen");
  85.         return -1;
  86.     }

  87.     return fd;
  88. }
复制代码


main.c:

  1. #include <stdio.h>
  2. #include <glib.h>

  3. int
  4. main(int argc, char **argv)
  5. {
  6.     GMainLoop *mainloop = g_main_loop_new(NULL, FALSE);
  7.     printf("%p: %s\n", argv[0], argv[0]);

  8.     g_main_loop_run(mainloop);

  9.     return 0;
  10. }
复制代码


Makefile:

  1. LSRC=                                           \
  2.     debug.c                                     \


  3. SRC=                                            \
  4.     main.c                                      \


  5. LOBJ = $(LSRC:.c=.o)

  6. OBJ = $(SRC:.c=.o)

  7. CFLAGS += -Wall -g -Werror -Wextra -Wfloat-equal -Wbad-function-cast -Wcast-qua\l -Winline -Wno-unused-parameter
  8. CFLAGS += `pkg-config --cflags glib-2.0` -I$(PWD)
  9. LFLAGS += `pkg-config --libs glib-2.0`

  10. LIBOUT = libdebug.so

  11. OUT = test

  12. all: $(LIBOUT) $(OUT)

  13. $(OUT): $(OBJ)
  14.     $(CC) $(CFLAGS) $(LFLAGS) $(OBJ) -L$(PWD) -o $(OUT)

  15. $(LIBOUT): $(LOBJ)
  16.     $(CC) -shared -Wl,-soname,$(LIBOUT) $(CFLAGS) $(LFLAGS) $(LOBJ) -o $(LIBOUT\)

  17. $(OBJ): %.o: %.c
  18.     $(CC) $(CFLAGS) -c $< -o $@

  19. $(LOBJ): %.o: %.c
  20.     $(CC) -fPIC $(CFLAGS) -c $< -o $@

  21. clean:
  22.     $(RM) $(LOBJ) $(LIBOUT) $(OUT) $(OBJ)
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-10-2 20:05:40 | 显示全部楼层
Post by lpsir
我就是希望能够读取内存中的一些东西
我其实是对某一时刻内存中放了什么东西感兴趣,呵呵

哪位大师能讲讲呢

如何明白的访问内存,而不是选一个值乱打印一通


在linux下是不能像DOS下那样随便就可以读谋个内存地址的数据的。 这是不仅是多用户多进程的特点,也是linux操作系统使用虚拟内存管理内存的原因。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表