utumno - 0

因为utumno0不可读, 开始以为用strace可以获取一些信息

最后只是调用write,并没什么用(从这里可以知道库函数puts最后是调用write来实现的)

最后利用xocopy把可执行代码dump出来

gcc xocopy.c -o xocopy -m32

./xocopy /utumno/utumno0

./xocopy -a 0x08049000 /utumno/utumno0

objdump -D utumno0.out
(Disassembly of section .rodata:)
 080484b8 <.rodata>:
 80484b8:	03 00                	add    (%eax),%eax
 80484ba:	00 00                	add    %al,(%eax)
 80484bc:	01 00                	add    %eax,(%eax)
 80484be:	02 00                	add    (%eax),%al

"aathaeyiew"
 80484c0:	61                   	popa
 80484c1:	61                   	popa
 80484c2:	74 68                	je     804852c <[email protected]+0x23c>
 80484c4:	61                   	popa
 80484c5:	65                   	gs
 80484c6:	79 69                	jns    8048531 <[email protected]+0x241>
 80484c8:	65                   	gs
 80484c9:	77 00                	ja     80484cb <[email protected]+0x1db>

"Read me! :P"
 80484cb:	52                   	push   %edx
 80484cc:	65                   	gs
 80484cd:	61                   	popa
 80484ce:	64 20 6d 65          	and    %ch,%fs:0x65(%ebp)
 80484d2:	21 20                	and    %esp,(%eax)
 80484d4:	3a 50 00             	cmp    0x0(%eax),%dl

到这里应该算就结束了,下面再介绍一种方法来解这一题

可以发现可执行文件在最后调用puts函数

这需要实现自己的puts函数替换库函数

自己实现的puts函数如下:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>

int puts(const char *s)
{
    int i;
    char *pt;

    // Variable to store the original puts function. just incase we need it.
    static void* (*my_puts)(const char*s) = NULL;

    if (!my_puts){
        // Store the original puts function.
        my_puts = dlsym(RTLD_NEXT, "puts");
    }

    // Start looking at stack addresses
    printf("%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-");
    // Display our hooked
    printf("Hooked-%s", s);
    // Run through the memory space.
    for( i = 0x804841a; i < 0x80484cb; i++) {
        pt = i;
        printf("%c", *pt);
        printf("");
    }
    return 0;
}
gcc -m32 -fPIC -c hookputs.c

ld -shared -m elf_i386 -o hookputs.so hookputs.o -ldl

objdump -d hookputs.so
Disassembly of section .text:

00000240 <puts>:
 240:	55                   	push   %ebp
 241:	89 e5                	mov    %esp,%ebp
 243:	53                   	push   %ebx
 244:	83 ec 24             	sub    $0x24,%esp

那么进入puts时的栈环境是

puts的参数

next main eip

ebp

ebx

0x24B

调用printf("%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-");时

栈顶是指向"%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-"的指针

10个%x把0x20B + ebx + ebp打印出来

最后两个%x把eip和puts的参数打印出来

为什么我们要把最后两个%x打印出来的地址之间的字符打印出来

倒数第二个%x打印出来的还是代码段的数据,

倒数第一个%x打印出来的是只读数据段的数据

那么如果utumno1的登陆密码是类似"aathaeyiew"这样初始化的,那么肯定存储在只读数据段中

那么理论上把整个只读数据段dump出就可能找到密码

程序是在结尾调用puts("Read me! :P"); 按照先后顺序,编译器很可能把"Read me! :P"放在只读数据段的最尾端

那么在代码段地址 和 只读数据段最尾端地址之间可以获取到所有只读数据段的数据

[email protected]:~/Desktop/utumno/utumno0# ssh [email protected]

[email protected]'s password: utumno0

[email protected]:~$ cd /tmp/utumno0

[email protected]:/tmp/utumno0$ gcc -m32 -fPIC -c hookputs.c

[email protected]:/tmp/utumno0$ ld -shared -m elf_i386 -o hookputs.so hookputs.o -ldl

[email protected]:/tmp/utumno0$ LD_PRELOAD="./hookputs.so" ltrace /utumno/utumno0
ERROR: ld.so: object './hookputs.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.
failed to initialize process 24891: No such file or directory
couldn't open program '/utumno/utumno0': No such file or directory
[email protected]:/tmp/utumno0$ f7fd52c0-0-0-ffffd5d8-f7ff0500-ffffd604-f7fd5210-1-f7fc9000-ffffd5d8-804841a-80484cb---
ffffd674-ffffd67c-f7e5510d-f7fc93c4-f7ffd000-804843b-80484c0Hooked-Read me! :Pffffffb8(?) 00() 00() 00() 00()
ffffffc9(?) ffffffc3(?) 66(f) ffffff90(?) 66(f) ffffff90(?) 66(f) ffffff90(?) 66(f) ffffff90(?) 66(f) ffffff90(?)
66(f) ffffff90(?) 66(f) ffffff90(?) ffffff90(?) 55(U) 57(W) 31(1) ffffffff(?) 56(V) 53(S) ffffffe8(?) fffffff5(?)
fffffffe(?) ffffffff(?) ffffffff(?) ffffff81(?) ffffffc3(?) 71(q) 12() 00() 00() ffffff83(?) ffffffec(?) 1c() ffffff8b(?)
6c(l) 24($) 30(0) ffffff8d(?) ffffffb3(?) 0c(...) ffffffff(?) ffffffff(?) ffffffff(?) ffffffe8(?) 3d(=) fffffffe(?)
ffffffff(?) ffffffff(?) ffffff8d(?) ffffff83(?) 08) ffffffff(?) ffffffff(?) ffffffff(?) 29()) ffffffc6(?) ffffffc1(?)
fffffffe(?) 02() ffffff85(?) fffffff6(?) 74(t) 27(') ffffff8d(?) ffffffb6(?) 00() 00() 00() 00() ffffff8b(?) 44(D)
24($) 38(8) ffffff89(?) 2c(,) 24($) ffffff89(?) 44(D) 24($) 08) ffffff8b(?) 44(D) 24($) 34(4) ffffff89(?) 44(D) 24($) 04()
ffffffff(?) ffffff94(?) ffffffbb(?) 08) ffffffff(?) ffffffff(?) ffffffff(?) ffffff83(?) ffffffc7(?) 01() 39(9) fffffff7(?)
75() ffffff90(?) ffffff90(?) ffffff90(?) ffffff90(?) ffffff90(?) ffffff90(?) ffffff90(?) ffffff90(?) ffffff90(?) ffffff90(?)
ffffff90(?) ffffff90(?) ffffff90(?) fffffff3(?) ffffffc3(?) 00() 00() 53(S) ffffff83(?) ffffffec(?) 08) ffffffe8(?) ffffff83(?)
fffffffe(?) ffffffff(?) ffffffff(?) ffffff81(?) ffffffc3(?) ffffffff(?) 11() 00() 00() ffffff83(?) ffffffc4(?) 08) 5b([)
ffffffc3(?) 03() 00() 00() 00() 01() 00() 02() 00() 61(a) 61(a) 74(t) 68(h) 61(a) 65(e) 79(y) 69(i) 65(e) 77(w) 00() 

xocopy.c

/* xocopy - Program for copying an executable with execute but no read perms.
 * Copyright (C) 2002, 2003 Dion Mendel.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

/*
 * A simple program to obtain a readable copy of an executable which has
 * execute, but no read permission.  It works by executing the process
 * - to load the process into memory - then dumping the memory image.
 *
 * Does not work for suid apps under linux 2.2.x.
 * Only works for elf files for which the elf header and program header table
 * are part of the loadable text segment (default for gcc).
 *
 * Generally, any data that appears in the file after loadable segments that
 * extend their size (usually shdr) will not be recovered.
 *
 * NOTE: This is a proof of concept program.  It is not robust.
 * NOTE: Does not work on linux kernels between 2.4.21-pre6 .. 2.4.21-rc2
 *       due to an incorrect ptrace patch being applied to those kernels.
 */

/* undefine this if there is no elf.h file on the system */
#define HAVE_ELF_H

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#ifdef HAVE_ELF_H
# include <elf.h>
#endif

#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

/*----------------------------------------------------------------------------*/
#ifdef __FreeBSD__
# define PTRACE_PEEKTEXT PT_READ_I
# define PTRACE_PEEKDATA PT_READ_D
# define PTRACE_TRACEME  PT_TRACE_ME
# define PTRACE_KILL     PT_KILL
#endif /* __FreeBSD__ */
/*----------------------------- ELF Definition -------------------------------*/
#ifndef HAVE_ELF_H

/* Type for a 16-bit quantity.  */
typedef u_int16_t Elf32_Half;

/* Types for signed and unsigned 32-bit quantities.  */
typedef u_int32_t Elf32_Word;

/* Type of addresses.  */
typedef u_int32_t Elf32_Addr;

/* Type of file offsets.  */
typedef u_int32_t Elf32_Off;

/* The ELF file header.  This appears at the start of every ELF file.  */

#define EI_NIDENT (16)

typedef struct
{
  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
  Elf32_Half    e_type;                 /* Object file type */
  Elf32_Half    e_machine;              /* Architecture */
  Elf32_Word    e_version;              /* Object file version */
  Elf32_Addr    e_entry;                /* Entry point virtual address */
  Elf32_Off     e_phoff;                /* Program header table file offset */
  Elf32_Off     e_shoff;                /* Section header table file offset */
  Elf32_Word    e_flags;                /* Processor-specific flags */
  Elf32_Half    e_ehsize;               /* ELF header size in bytes */
  Elf32_Half    e_phentsize;            /* Program header table entry size */
  Elf32_Half    e_phnum;                /* Program header table entry count */
  Elf32_Half    e_shentsize;            /* Section header table entry size */
  Elf32_Half    e_shnum;                /* Section header table entry count */
  Elf32_Half    e_shstrndx;             /* Section header string table index */
} Elf32_Ehdr;

#define EI_CLASS        4               /* File class byte index */
#define ELFCLASS32      1               /* 32-bit objects */

/* Legal values for e_type (object file type).  */
#define ET_EXEC         2               /* Executable file */
#define ET_DYN          3               /* Shared object file */

/* Program segment header.  */

typedef struct
{
  Elf32_Word    p_type;                 /* Segment type */
  Elf32_Off     p_offset;               /* Segment file offset */
  Elf32_Addr    p_vaddr;                /* Segment virtual address */
  Elf32_Addr    p_paddr;                /* Segment physical address */
  Elf32_Word    p_filesz;               /* Segment size in file */
  Elf32_Word    p_memsz;                /* Segment size in memory */
  Elf32_Word    p_flags;                /* Segment flags */
  Elf32_Word    p_align;                /* Segment alignment */
} Elf32_Phdr;

/* Legal values for p_type (segment type).  */

#define PT_NULL         0               /* Program header table entry unused */
#define PT_LOAD         1               /* Loadable program segment */

#endif     /* Elf Definition */
/*----------------------------------------------------------------------------*/

/* this is the word datatype returned by ptrace for PEEK* */
#define PTRACE_WORD int32_t

/*
 * PAGE_SIZE    - the size of a memory page
 * LO_USER      - the lowest address accessible from user space  (% PAGE_SIZE)
 * HI_USER      - the highest address accessible from user space  (% PAGE_SIZE)
 */
#if defined (__linux__)
#  define PAGE_SIZE 4096U
#  define LO_USER   4096U
#  define HI_USER   0xc0000000U
#elif defined (__FreeBSD__)
#  define PAGE_SIZE 4096U
#  define LO_USER   4096U
#  define HI_USER   0xbfc00000U
#else
   ERROR UNKNOWN OPERATING SYSTEM
#endif

#define PAGE_MASK               (~(PAGE_SIZE-1))

/* ---------------- useful functions possibly found in libc ---------------- */

static char *
basename (char *pathname)
{
   char *ptr;
   ptr = strrchr(pathname, '/');
   return ptr ? ptr + 1 : pathname;
}

static int
tolower (int c)
{
   if ('A' <= c && c <= 'Z')
      return c + 'a' - 'A';
   return c;
}

/*
 * Reads a given number of bytes from the text segment.
 * num_bytes must be a multiple of the word size
 */
static int
read_text_segment (pid_t pid, unsigned int addr, char *buf, size_t num_bytes)
{
   int i;
   int num_words;

   /* determine number of words required to read num_bytes */
   num_words = num_bytes / sizeof(PTRACE_WORD);
   if ((num_bytes % sizeof(PTRACE_WORD)) != 0)
      num_words++;

   for (i = 0; i < num_words; i++) {
      *(((PTRACE_WORD *) buf) + i ) = ptrace(PTRACE_PEEKTEXT, pid,
                                             addr + i * sizeof(PTRACE_WORD), 0);
      if (errno != 0) {
         char msg[1024];
         snprintf(msg, sizeof(msg), "ptrace(PTRACE_PEEKTEXT, pid, 0x%08x, 0)",
                  addr + i * sizeof(PTRACE_WORD));
         perror(msg);
         return 0;
      }
   }

   return 1;
}

/*---------------------------------------------------------------------------*/

#define LO_PAGE_ADDR(phdr) ((phdr)->p_offset & PAGE_MASK)
#define HI_PAGE_ADDR(phdr) (((phdr)->p_offset + ((phdr)->p_filesz) + PAGE_SIZE - 1) & PAGE_MASK)

#define MIN(a,b) ((a) < (b) ? (a) : (b))

#define INTERSECTS(off1, size1, off2, size2) ( ((off1) < (off2)) ? ((off2) < (off1) + (size1)) : ((off1) < ((off2) + (size2))) )

/*
 * Prints warning message for the bytes in the file that couldn't be recovered.
 * Uses 0/0 for offset/size to signal end of all lost data.
 */
static void
warn_lost_data (pid_t pid, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr,
                unsigned int offset, unsigned int size)
{
   static unsigned int last_offset = 0;   /* for recording last offset */
   static unsigned int last_size = 0;     /* and size - initialised to zero */
   int p;

   if (offset != 0 && size != 0) {
      if ((last_offset + last_size) == offset) {
         /* join offsets */
         last_size += size;
         return;
      }
   }

   if (last_offset != 0 && last_size != 0) {
      fprintf(stderr, "could not recover data - %d bytes at file offset %d\n",
              last_size, last_offset);

      for (p = 0; p < ehdr->e_phnum; p++) {
         if (phdr[p].p_type != PT_NULL) {
            if (INTERSECTS(last_offset, last_size,
                           phdr[p].p_offset, phdr[p].p_filesz))
            {
               fprintf(stderr, " ! data from phdr[%d] was not recovered\n", p);
            }
         }
      }

      if ((ehdr->e_shnum != 0) &&
           INTERSECTS(last_offset, last_size, ehdr->e_shoff,
                      ehdr->e_shnum * ehdr->e_shentsize))
      {
         fprintf(stderr, " ! section header table was not recovered\n");
      }
   }

   /* record this offset and size */
   last_offset = offset;
   last_size   = size;
}

/*
 * Writes the memory pages to the given filename.  Requires that ehdr and phdr
 * are in loaded memory.
 */
static int
create_file (char *filename, pid_t pid, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr,
             size_t file_size)
{
   FILE *fptr;
   Elf32_Phdr *this_phdr;
   char page[PAGE_SIZE];
   int i, p;
   int num_pages;
   unsigned int *pages;
   unsigned int end_segment_address;
   int okay, last_page;

   num_pages = (file_size + PAGE_SIZE - 1) / PAGE_SIZE;
   pages = malloc(num_pages * sizeof(*pages));

   if (pages == NULL) {
      fprintf(stderr, "malloc failed\n");
      return 0;
   }

   /* map memory pages to position in file */
   for (i = 0; i < num_pages; i++) {
      pages[i] = 0;
      for (p = 0; p < ehdr->e_phnum; p++) {
         this_phdr = &phdr[p];
         if (this_phdr->p_type == PT_LOAD) {
            if (LO_PAGE_ADDR(this_phdr) <= (i * PAGE_SIZE) &&
                  ((i + 1) * PAGE_SIZE) <= HI_PAGE_ADDR(this_phdr))
            {
               /* check for lost data in the last page of the segment */
               end_segment_address = this_phdr->p_offset + this_phdr->p_filesz;
               last_page = end_segment_address < ((i + 1) * PAGE_SIZE);
               if (last_page && (this_phdr->p_memsz > this_phdr->p_filesz)) {
                  warn_lost_data(pid, ehdr, phdr, end_segment_address,
                                 ((i + 1) * PAGE_SIZE) - end_segment_address);
               }

               pages[i] = phdr[p].p_vaddr - phdr[p].p_offset + (i * PAGE_SIZE);
               break;
            }
         }
      }

      /* warn about lost data if no memory page maps to file */
      if (pages[i] == 0)
         warn_lost_data(pid, ehdr, phdr, i * PAGE_SIZE, PAGE_SIZE);
   }
   /* signal that an attempt to recover all pages has been made */
   warn_lost_data(pid, ehdr, phdr, 0, 0);

   /* write memory pages to file */
   okay = 0;
   if ( (fptr = fopen(filename, "wb")) != NULL) {
      for (i = 0; i < num_pages; i++) {
         if (pages[i] != 0) {
            if (! read_text_segment(pid, pages[i], page, PAGE_SIZE)) {
               fclose(fptr);
               free(pages);
               return 0;
            }
         }
         else {
            memset(page, '\0', PAGE_SIZE);
         }
         fwrite(page, 1, MIN(file_size, PAGE_SIZE), fptr);
         file_size -= PAGE_SIZE;
      }

      fclose(fptr);
      okay = 1;
   }
   else {
      char msg[1024];
      snprintf(msg, sizeof(msg), "couldn't create file `%s'", filename);
      perror(msg);
   }

   free(pages);

   return okay;
}

/*
 * Error check before writing the memory pages to disk.
 */
static int
save_to_file (char *filename, pid_t pid, unsigned int addr, size_t file_size)
{
   char page[PAGE_SIZE];
   Elf32_Ehdr *ehdr;
   Elf32_Phdr *phdr;
   int okay;

   okay = 0;
   if (read_text_segment(pid, addr, page, PAGE_SIZE)) {
      /* ensure 32bit elf binary */
      ehdr = (Elf32_Ehdr *) page;
      if (page[EI_CLASS] == ELFCLASS32 && ehdr->e_type == ET_EXEC) {

         /* ensure program header table is in same page as elf header */
         if ((ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize) < PAGE_SIZE) {
            phdr = (Elf32_Phdr *) (page + ehdr->e_phoff);
            okay = create_file(filename, pid, ehdr, phdr, file_size);
         }
         else {
            fprintf(stderr, "program header table could not be found\n");
         }
      }
      else {
         fprintf(stderr, "no 32bit elf executable, found at addr 0x%08x\n",
                 addr);
      }
   }

   return okay;
}

#define NUM_ELF_HEADERS 10

/*
 * Searches memory for an elf header.
 */
static unsigned int
find_elf_header (pid_t pid)
{
   int i;
   char *elf_hdr = "\177ELF";
   Elf32_Ehdr hdr;
   unsigned int possible[NUM_ELF_HEADERS];
   int num_possible;
   unsigned int addr;
   PTRACE_WORD word;
   int found_elf_header;

   num_possible = 0;

   /* search each page to see if elf header is found */
   for (addr = LO_USER; addr < HI_USER; addr += PAGE_SIZE) {
      found_elf_header = 0;

      word = ptrace(PTRACE_PEEKTEXT, pid, addr, 0);
      if ((errno == 0) && (word == *((PTRACE_WORD *) elf_hdr))) {
         if (read_text_segment(pid, addr, (char *) &hdr, sizeof(hdr))) {
            if (hdr.e_type == ET_EXEC)
              found_elf_header = 1;
            else if (hdr.e_type == ET_DYN)
               fprintf(stderr, "discarding shared library at "
                     "virtual memory address 0x%08x\n", addr);
         }
      }
      if (found_elf_header) {
         if (num_possible == NUM_ELF_HEADERS) {
            fprintf(stderr, "too many possible elf headers found (> %d)\n",
                    NUM_ELF_HEADERS);
            return 0;
         }
         possible[num_possible] = addr;
         num_possible++;
      }
   }

   if (num_possible == 0) {
      /* no elf header found */
      return 0;
   }
   else if (num_possible == 1) {
      /* a single elf header was found */
      fprintf(stdout, "using elf header at virtual memory address "
                      "         0x%08x\n", possible[0]);
      return possible[0];
   }
   else {
      /* need to resolve conflicts - let user decide */
      fprintf(stderr, "multiple elf headers found:\n");
      for (i = 0; i < num_possible; i++) {
         printf("  0x%08x\n", possible[i]);
      }
      return 0;
   }
}

int
main (int argc, char *argv[])
{
   char *filename;
   char out_filename[8192];
   char buf[1024];
   struct stat stat_buf;
   pid_t pid;
   int status;
   int ret_val;
   size_t file_size;
   unsigned int addr;
   int bad_usage;

   filename = NULL;
   addr = 0;

   /* process args: assigning values to bad_usage filename and possibly addr */
   bad_usage = 1;
   if (argc == 2) {
      filename = argv[1];
      bad_usage = 0;
   }
   else if (argc == 4) {
      filename = argv[3];

      if (strcmp(argv[1], "-a") == 0) {
         if ((argv[2][0] == '0') && (tolower(argv[2][1]) == 'x'))
            addr = strtol(argv[2], NULL, 16);
         else
            addr = strtol(argv[2], NULL, 10);
         if (errno != ERANGE)
            bad_usage = 0;
      }
   }

   if (bad_usage) {
      fprintf(stderr, "Obtains an executable copy of a binary with execute "
                      "but no read permission\n"
                      "Usage: %s [-a addr] <file>\n"
                      "  where addr is the memory address of the elf header\n",
                      argv[0]);
      exit(EXIT_FAILURE);
   }

   if (stat(filename, &stat_buf) != 0) {
      snprintf(buf, sizeof(buf), "couldn't stat file `%s'", filename);
      perror(buf);
      exit(EXIT_FAILURE);
   }

   /* remember file size of original file */
   file_size = stat_buf.st_size;

   if ( (pid = fork()) == 0) {
      /* child */
      if (ptrace(PTRACE_TRACEME, 0, 0, 0) == 0) {
         execl(filename, filename, NULL);
         snprintf(buf, sizeof(buf), "couldn't exec `%s'", filename);
         perror(buf);
      }
      else {
         perror("ptrace(PTRACE_TRACEME, ...)");
      }
      _exit(EXIT_FAILURE);
   }

   ret_val = EXIT_FAILURE;
   if (waitpid(pid, &status, WUNTRACED) == pid) {
      if (!WIFEXITED(status)) {
         /* SIGTRAP is delivered to child after execve */
         if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
            if (addr == 0)
               addr = find_elf_header(pid);
            if (addr != 0) {
               snprintf(out_filename, sizeof(out_filename), "%s.out",
                        basename(filename));

               if (save_to_file(out_filename, pid, addr, file_size)) {
                  chmod(out_filename, 00755);
                  fprintf(stdout, "created file `%s'\n", out_filename);
                  ret_val = EXIT_SUCCESS;
               }
            }
            else {
               fprintf(stderr, "couldn't find elf header in memory\n");
            }
         }
         else {
            fprintf(stderr, "didn't receive SIGTRAP after execve\n");
         }

         /* kill child as we are finished */
         ptrace(PTRACE_KILL, pid, 0, 0);
      }
   }
   else {
      perror("waitpid");
   }

   return(ret_val);
}
时间: 2024-08-02 23:25:17

utumno - 0的相关文章

鬃嘴释怀说太多就成真不了。

子阻撞砖奏尊仔籽着 释怀说太多就成真不了. http://passport.baidu.com/?business&un=vip&un=%E5%A4%A9%E6%B0%B4%E4%B8%8A%E9%97%A8%E8%BF%99%E5%B0%8F%E5%A7%90#0 http://passport.baidu.com/?business&un=vip&un=%E7%99%BD%E9%93%B6%E4%B8%8A%E9%97%A8%E8%BF%99%E5%B0%8F%E5%A

澜星粘鼐贩逊耐盼系甭妊倏纪傲傲sdfghjk

http://passport.baidu.com/?business&un=R&un=%E5%A4%A7%E5%AE%81%E6%A1%91%E6%8B%BF%E9%80%9A%E5%B0%8F%E5%A7%90#0 http://passport.baidu.com/?business&un=R&un=%E4%B9%A1%E5%AE%81%E6%A1%91%E6%8B%BF%E9%80%9A%E5%B0%8F%E5%A7%90#0 http://passport.bai

在Ubuntu14.04上OpenStack Juno安装部署

在Ubuntu14.04上OpenStack Juno安装部署 0 安装方式 0.1 安装方式 安装方式 说明 目标 备注 单结点 一台服务器运行所有的nova-xxx组件,同时也驱动虚拟实例. 这种配置只为尝试Nova,或者为了开发目的进行安装.   1控制节点+N个计算节点 一个控制结点运行除nova-compute外的所有nova-services,然后其他compute结点运行nova-compute.所有的计算节点需要和控制节点进行镜像交互,网络交互,控制节点是整个架构的瓶颈. 这种配

2008 SCI 影响因子(Impact Factor)

Excel download 期刊名缩写 影响因子 ISSN号 CA-CANCER J CLIN 74.575 0007-9235 NEW ENGL J MED 50.017 0028-4793 ANNU REV IMMUNOL 41.059 0732-0582 NAT REV MOL CELL BIO 35.423 1471-0072 PHYSIOL REV 35.000 0031-9333 REV MOD PHYS 33.985 0034-6861 JAMA-J AM MED ASSOC 3

使用 IDEA 创建 Maven Web 项目 (异常)- Disconnected from the target VM, address: &#39;127.0.0.1:59770&#39;, transport: &#39;socket&#39;

运行环境: JDK 版本:1.8 Maven 版本:apache-maven-3.3.3 IDEA 版本:14 maven-jetty-plugin 配置: <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <webAppSourceDirectory>${pro

Linux下WebSphereV8.5.5.0 安装详细过程

Linux下WebSphereV8.5.5.0 安装详细过程 自WAS8以后安装包不再区别OS,一份介质可以安装到多个平台.只针对Installation Manager 进行了操作系统的区分 ,Websphere产品介质必须通过专门的工具Install Managere安装.进入IBM的官网http://www.ibm.com/us/en/进行下载.在云盘http://yun.baidu.com/share/linkshareid=2515770728&uk=4252782771 中是Linu

Centos7.2部署.Net Core2.0 WebApi

部署前准备 1.VisualStudio2017+.netcore2.0SDK 2.Centos7.2 3.SecureCRT,Xftp(根据自己喜好) 创建WebApi项目 修改Program.cs中的BuildWebHost方法为(不改也可,core默认使用Kestrel作为Server) public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseKestrel()

Apache Storm 1.1.0 中文文档 | ApacheCN

前言  Apache Storm 是一个免费的,开源的,分布式的实时计算系统. 官方文档: http://storm.apache.org 中文文档: http://storm.apachecn.org ApacheCN 最近组织了翻译 Storm 1.1.0 中文文档 的活动,整体 翻译进度 为 96%. 感谢大家参与到该活动中来 感谢无私奉献的 贡献者,才有了这份 Storm 1.1.0 中文文档 感谢一路有你的陪伴,我们才可以做的更好,走的更快,走的更远,我们一直在努力 ... 网页地址:

Vue.js系列之项目搭建(vue2.0 + vue-cli + webpack )

1.安装node node.js环境(npm包管理器) cnpm npm的淘宝镜像 从node.js官网下载并安装node,安装过程很简单,一路"下一步"就可以了(傻瓜式安装).安装完成之后,打开命令行工具,输入 node -v,如果出现相应的版本号,则说明安装成功. npm包管理器,是集成在node中的,所以,直接输入 npm -v就会显示出npm的版本信息. 2.安装cnpm 在命令行中输入 npm install -g cnpm --registry=http://registr