Exemplo n.º 1
0
static void
sort_and_name_all(struct RP_class *root)
{
  /* first name RuntimeClass struct */
  misc_buffer1[0] = 'R';
  misc_buffer1[1] = 'T';
  misc_buffer1[2] = '_';
  get_many_bytes(get_long(root->CRuntime), misc_buffer1 + 3, root->namelen);
  // 29 APR 2003 - rpd support
  if ( p_pool != NULL && root->vtbl )
   fill_vtbl(misc_buffer1 + 3, root->vtbl);

  misc_buffer1[3 + root->namelen] = 0x0;
  set_name(root->CRuntime, misc_buffer1, SN_AUTO);
  /* next name vtbl if found */
  if ( NULL != root->vtbl )
  {
    misc_buffer1[0] = 'v';
    misc_buffer1[1] = 't';
    misc_buffer1[2] = 'b';
    misc_buffer1[3] = 'l';
    misc_buffer1[4] = '_';
    get_many_bytes(get_long(root->CRuntime), misc_buffer1 + 5, root->namelen);
    misc_buffer1[5 + root->namelen] = 0x0;
    set_name(root->vtbl, misc_buffer1, SN_AUTO);
  }
  /* sort children by name */
  if ( !root->total )
   return;
  qsort(root->children, root->total, sizeof(struct RP_class *), rt_compare_names);
  /* and finally do it recirsive for all children */
  int i;
  for ( i = 0; i < root->total; i++ )
   sort_and_name_all(root->children[i]);
}
Exemplo n.º 2
0
//---------------------------------------------------------------------------
static bool extractData(uint32 off)
{
    IMAGE_RESOURCE_DATA_ENTRY rd;

    if ( off + sizeof(rd) > ResTop ) return false;
    if ( !get_many_bytes(ResBase + off, &rd, sizeof(rd)) ) return false;

    if ( rd.OffsetToData >= ImgSize
            || rd.Size > ImgSize
            || rd.OffsetToData + rd.Size > ImgSize ) return false;

    void *data = qalloc(rd.Size);
    if ( data == NULL )
    {
        msg("Not enough memory for resources\n");
        return false;
    }
    bool res = false;
    if ( get_many_bytes(curmod.startEA + rd.OffsetToData, data, rd.Size) )
    {
        store(data, rd.Size);
        res = true;
    }
    qfree(data);
    return res;
}
Exemplo n.º 3
0
static int __cdecl
rt_compare_names(const void *a, const void *b)
{
  struct RP_class *a_c = *(struct RP_class **)a;
  struct RP_class *b_c = *(struct RP_class **)b;

  get_many_bytes(get_long(a_c->CRuntime), misc_buffer1, a_c->namelen);
  get_many_bytes(get_long(b_c->CRuntime), misc_buffer2, b_c->namelen);
  misc_buffer1[a_c->namelen] = 0x0;
  misc_buffer2[b_c->namelen] = 0x0;
  return strcmp(misc_buffer1, misc_buffer2);
}
Exemplo n.º 4
0
bool find_parse_ip(ea_t ea, bool parsecode)
{
	char id[16];
	// Attempt to identify program start from ip
	get_many_bytes(ea, id, 16);
	if (memcmp(id, "SEGA SEGASATURN ", 16) != 0)
		return false;

	make_ascii_string(ea, 16, ASCSTR_C);
   make_ascii_string(ea+0x10, 16, ASCSTR_C);
	make_ascii_string(ea+0x20, 10, ASCSTR_C);
	make_ascii_string(ea+0x2A, 6, ASCSTR_C);
	make_ascii_string(ea+0x30, 8, ASCSTR_C);
	make_ascii_string(ea+0x38, 8, ASCSTR_C);
	make_ascii_string(ea+0x40, 10, ASCSTR_C);
	make_ascii_string(ea+0x4A, 6, ASCSTR_C);
	make_ascii_string(ea+0x50, 16, ASCSTR_C);
	make_ascii_string(ea+0x60, 0x70, ASCSTR_C);
	doByte(ea+0xD0, 16);
	doDwrd(ea+0xE0, 4);
	doDwrd(ea+0xE4, 4);
	doDwrd(ea+0xE8, 4);
	doDwrd(ea+0xEC, 4);
	doDwrd(ea+0xF0, 4);
	add_func(get_long(ea+0xF0), BADADDR);
	doDwrd(ea+0xF4, 4);
	doDwrd(ea+0xF8, 4);
	doDwrd(ea+0xFC, 4);
	if (parsecode)
	   add_func(ea+0x100, BADADDR);
	return true;
}
Exemplo n.º 5
0
ByteSize IdaByteSource::readBytes(ByteAddr addr, void *buf, ByteSize size) const {
#ifdef NC_USE_THREADS
#error You are trying to shoot your leg. IDA API is not thread-safe.
#endif

    if (get_many_bytes(checked_cast<ea_t>(addr), buf, checked_cast<ssize_t>(size))) {
        return size;
    }

    char *charBuf = static_cast<char *>(buf);
    ByteSize i;
    for (i = 0; i < size; i++) {
        ea_t idaAddr = checked_cast<ea_t>(addr + i);

        char value = get_byte(idaAddr);
        if (value == 0) {
            flags_t flags = getFlags(idaAddr);
            if (!hasValue(flags)) {
                break;
            }
        }

        *charBuf++ = value;
    }
    return i;
}
Exemplo n.º 6
0
//---------------------------------------------------------------------------
static bool extractDirectory(uint32 off, int level)
{
    IMAGE_RESOURCE_DIRECTORY  rd;

    if ( off + sizeof(rd) >= ResTop )
        return false;
    if ( !get_many_bytes(ResBase + off, &rd, sizeof(rd)) )
        return false;

    off += sizeof(rd);
    if ( rd.NumberOfNamedEntries != 0 )
    {
        if ( level == 2 )           // language must be ONLY numbered
            return false;
        do
        {
            if ( !extractEntry(off, level, true) )
                return false;
            off += sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);
        } while ( --rd.NumberOfNamedEntries );
    }
    if ( rd.NumberOfIdEntries != 0 )
    {
        do
        {
            if ( !extractEntry(off, level, false) )
                return false;
            off += sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);
        } while ( --rd.NumberOfIdEntries );
    }
    return true;
}
Exemplo n.º 7
0
  HRESULT STDMETHODCALLTYPE ReadExecutableAtRVA(
   DWORD  relativeVirtualAddress,
   DWORD  cbData,
   DWORD* pcbData,
   BYTE   data[] )
  {
#ifdef PDBTOTIL
    if ( mem_reader != NULL )
    {
      uint32 read;
      bool ok = mem_reader(m_load_address + relativeVirtualAddress, cbData, data, &read);
      if ( !ok )
        return E_FAIL;
      *pcbData = read;
      return S_OK;
    }
#endif
#ifndef BUILDING_EFD
#ifndef PDBTOTIL
    if ( get_many_bytes(m_load_address + relativeVirtualAddress, data, cbData) )
    {
      *pcbData = cbData;
      return S_OK;
    }
#endif
#else
    qnotused(relativeVirtualAddress);
    qnotused(cbData);
    qnotused(pcbData);
    qnotused(data);
#endif
    return S_FALSE;
  }
Exemplo n.º 8
0
static int __cdecl
rt_find_by_name(const void *key, const void *elem)
{
  const struct RP_class *cmp_with = *(const struct RP_class **)elem;
  get_many_bytes(get_long(cmp_with->CRuntime), misc_buffer1, cmp_with->namelen);
  misc_buffer1[cmp_with->namelen] = 0x0;
  return strcmp((const char *)key, misc_buffer1);
}
Exemplo n.º 9
0
//allocates memory and stores a copy of each
//byte of the given area
uchar *get_segment_data(ea_t s_a, ea_t e_a, ea_t size)
{
	uchar *mem;

	mem = (uchar *)malloc(size+1);
	
	get_many_bytes(s_a,mem,size);
	return mem;
}
Exemplo n.º 10
0
static int is_gotbase_call(ea_t addr)
{
  unsigned char buf[4];
  get_many_bytes(addr, buf, 4);
  if ( buf[0] == 0x8B &&
       buf[1] == 0x1C &&
       buf[2] == 0x24 &&
       buf[3] == 0xC3 )
   return 1;
  return 0;
}
Exemplo n.º 11
0
//--------------------------------------------------------------------------
// find Windows 9x import thunk
static bool resolve_thunk(ea_t ea)
{
  push_jump_insns_t thunk;

  if ( !get_many_bytes(ea, &thunk, sizeof(thunk))
    || thunk.push != 0x68 || thunk.jmp != 0xE9
    || thunk.ea < 0x80000000 || thunk.ea >= 0xC0000000 )
  {
    return false;
  }

  if ( !calc_thunk_target(uint32(ea), thunk.ea) )
    msg("%a: Thunked import (%08X) without references\n", ea, thunk.ea);
  return true;
}
Exemplo n.º 12
0
void mark_name_from_static_RT(ea_t ea)
{
  ea_t rt = check_for_cruntimeclass( get_long(ea) );
  if ( !rt || rt == BADADDR )
   return;
  size_t len = check_for_RTStruct(rt);
  if ( len )
  {
    char *name = (char *)qalloc(len + 1);
    get_many_bytes(get_long(rt), name, len);
    name[len] = 0;
    set_vtbl_name(name, ea);
    qfree(name);
  }
}
Exemplo n.º 13
0
pdb_class *try_to_find_from_rt(ea_t ea, char **name, bool *free_name)
{
  pdb_class *res = NULL;
  if ( !ea || ea == BADADDR )
   return NULL;
  // check for ref to const parent CRunTime class from DLL
  ea_t rt = check_for_cruntimeclass2(ea);
  if ( rt )
  {
    res = try_find_by_name(rt, name, free_name, false);
    if ( res )
     return res;
  }
  // check for ref to base CRunTime class
  rt = check_for_cruntimeclass(ea);
  if ( rt )
  {
    res = try_find_by_name(rt, name, free_name);
    if ( res )
     return res;
  }
  size_t len;
  // check for name from static CRunTime class
  if ( !rt )
  {
    len = check_for_RTStruct(ea);
    rt = ea;
  }
  else
   len = check_for_RTStruct(rt);
  if ( len )
  {
    *name = (char *)qalloc(len + 1);
    get_many_bytes(get_long(rt), *name, len);
    (*name)[len] = 0;
    setter(*name, rt, 0, true);
    res = p_pool->find_class(*name);
    if ( res )
    {
     *free_name = true;
     return res;
    }
    qfree(*name);
    // lets check all hierarchy
    res = try_to_find_from_rt(get_long(rt + 0x10), name, free_name);
  }
  return res;
}
Exemplo n.º 14
0
int sig_add_address(psig_t * sig, short opcodes[256], ea_t ea, bool b, bool line, char options)
{
	unsigned char byte;
	unsigned char buf[200];
	uint32 s, i;
	bool call;
	bool cj;
	ea_t tea;
	flags_t f;

	if (line)
		dline_add(&sig->dl, ea, options);

	if (is_jump(sig, ea, &call, &cj))
		return -1;

	byte = get_byte_with_optimization(ea);

	if (remove_instr(byte, ea))
		return -1;

	sig->lines++;
	opcodes[byte]++;

	if (!b && !call)
	{
		if (cj)
		{
			buf[0] = byte;
			s = 1;
		}
		else
		{
			s = (uint32)get_item_size(ea);
			if (s > sizeof(buf)) s = sizeof(buf);
			get_many_bytes(ea, buf, s);
		}

		for (i=0; i<s; i++)
		{
			sig->crc_hash += buf[i];
			sig->crc_hash += ( sig->crc_hash << 10 );
			sig->crc_hash ^= ( sig->crc_hash >> 6 );
		}
	}
	else if (b)
Exemplo n.º 15
0
void
output_rt_tree(FILE *fp, struct RP_class *root, int margin)
{
  if ( NULL == root )
   return;
  rt_put_margin(margin,fp);
  get_many_bytes(get_long(root->CRuntime), misc_buffer1, root->namelen);
  misc_buffer1[root->namelen] = 0x0;
  if ( root->vtbl )
   fprintf(fp, "%s: adr 0x%X, vtbl 0x%X\n", misc_buffer1, root->CRuntime, root->vtbl);
  else
   fprintf(fp, "%s: adr 0x%X\n", misc_buffer1, root->CRuntime );
  int i;
  margin += 4;
  for ( i = 0; i < root->total; i++ )
   output_rt_tree(fp, root->children[i], margin);
}
Exemplo n.º 16
0
/*
 * helper function to find GUIDs in data segment and label them
 */
void
find_guids(ea_t start, ea_t end)
{
    uint32_t table_size = sizeof(guid_table)/sizeof(*guid_table);
    ea_t current_addr = start;
    int match = 0;
    /* go over all the data segment searching for GUIDs */
    while (current_addr < end)
    {
        /* match against table entries */
        for (uint32_t i = 0; i < table_size; i++)
        {
            EFI_GUID tmp;
            get_many_bytes(current_addr, &tmp, sizeof(EFI_GUID));
            if (tmp.Data1 == guid_table[i].guid.Data1 &&
                tmp.Data2 == guid_table[i].guid.Data2 &&
                tmp.Data3 == guid_table[i].guid.Data3 &&
                memcmp(tmp.Data4, guid_table[i].guid.Data4, sizeof(tmp.Data4)) == 0)
            {
                set_name(current_addr, (const char*)guid_table[i].name, SN_CHECK);
                doDwrd(current_addr, 4);
                doDwrd(current_addr+4, 4);
                doDwrd(current_addr+8, 4);
                doDwrd(current_addr+12, 4);
                static char string[256] = {0};
                qsnprintf(string, sizeof(string), "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
                         guid_table[i].guid.Data1, guid_table[i].guid.Data2, guid_table[i].guid.Data3,
                         guid_table[i].guid.Data4[0], guid_table[i].guid.Data4[1], guid_table[i].guid.Data4[2], guid_table[i].guid.Data4[3],
                         guid_table[i].guid.Data4[4], guid_table[i].guid.Data4[5], guid_table[i].guid.Data4[6], guid_table[i].guid.Data4[7]);
                set_cmt(current_addr, string, 0);
                match = 1;
                break;
            }
        }
        /* no need to check all 16 bytes if we found a match */
        if (match)
        {
            current_addr += sizeof(EFI_GUID);
            match = 0;
        }
        else
        {
            current_addr++;
        }
    }
}
Exemplo n.º 17
0
/* tries to find CObject class */
ea_t
find_root(ea_t start, bool silent)
{
  char buffer[ROOT_LEN+1];
  /* check what we get */
  size_t len = check_for_RTStruct(start);
  if ( !len ) /* hm, lets try to find in -20..+20 range */
   for ( ea_t cptr = start - 20; cptr < cptr + 24; cptr += sizeof(ea_t) )
   {
     if ( start == cptr )
      continue;
     if ( len = check_for_RTStruct(cptr) )
     {
       start = cptr;
       break;
     }
   }
  if ( !len )
  {
    if ( !silent )
      warning("Passed address (0x%X) dont seems to be CRuntimeClass", start);
    return NULL;
  }
  while( NULL != start )
  {
    if ( len == ROOT_LEN ) /* Hm, may be */
    {
      if ( !get_many_bytes(get_long(start), buffer, ROOT_LEN) )
      {
        if ( !silent )
          warning("Cannot get %d bytes at 0x%X", len, get_long(start) );
        return NULL;
      }
      if ( !strncmp(buffer, (const char *)root_name, ROOT_LEN) )
       return start;
    }
    start = get_long(start+16);
    len = check_for_RTStruct(start);
    if ( !len )
     break;
  }
  if ( !silent )
    warning("Cannot find root");
  return NULL;
}
Exemplo n.º 18
0
//---------------------------------------------------------------------------
static bool initPtrs(const char *fname)
{
    IMAGE_DATA_DIRECTORY  res;
    ea_t nth;

    nth = get_long(curmod.startEA + 0x3C) + curmod.startEA;

    size_t off = offsetof(IMAGE_NT_HEADERS,
                          OptionalHeader.DataDirectory
                          [IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);

    if ( !get_many_bytes(nth + off, &res, sizeof(res))
            || !res.VirtualAddress
            || !res.Size )
    {
        msg("There are no resources in the module\n");
        return false;
    }

    ResBase = curmod.startEA + res.VirtualAddress;
    ResTop  = res.Size;
    ImgSize = curmod.endEA - curmod.startEA;

    int minres = 2*sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)+3*sizeof(IMAGE_RESOURCE_DIRECTORY);
    if ( (res.Size & 3) != 0
            || res.Size <= minres
            || res.VirtualAddress >= ImgSize
            || res.Size >= ImgSize
            || res.Size + res.VirtualAddress > ImgSize )
    {
        msg("Invalid resource descriptor\n");
        return false;
    }

    fr = qfopen(fname, "wb");
    if ( fr == NULL )
    {
        msg("Can not create the output file '%s' for the resources\n", fname);
        return false;
    }

    return true;
}
Exemplo n.º 19
0
// this function find the size of the jump table for indirect switches
// (indirect switches have the values table which contains indexes into
// the jump table)
// in: si->ncases has the size of the values table
// out: si->jcases is initialized
static bool find_jtable_size(switch_info_ex_t &si)
{
  int size = 0;
  ea_t ea = si.values;
  int vsize = si.get_vtable_element_size();
  for ( int i=0; i < si.ncases; i++,ea+=vsize )
  {
    uint64 v = 0;
    if ( !get_many_bytes(ea, &v, vsize) )
      break;
    if ( size < v )
      size = (int)v;
  }
  if ( size == 0 )
    return false;
  size++;
  si.jcases = size;
  return true;
}
void IDAMemCopyPaste::copy_buffer(ea_t eaStartAddr, ea_t eaEndAddr) 
{
	ssize_t size;

	// Work out the size, make sure it doesn't exceed the buffer
	// we have allocated.
	size = eaEndAddr - eaStartAddr;
	if (size > MAX_COPYPASTE)
	{
		warning("You can only copy a max of %d bytes\n", MAX_COPYPASTE);
		return;
	}
	// Get the bytes from the file, store it in our buffer
	if (get_many_bytes(eaStartAddr, data, size)) 
	{
		msg("Successfully copied %d bytes from %a into memory.\n", size, eaStartAddr);
	}
	else
	{
		msg("FAILED to copy %d bytes from %a into memory.\n", size, eaStartAddr);
	}
}
Exemplo n.º 21
0
int  __stdcall GetBytes(__int64 offset, void *buf, int length){ return get_many_bytes((ea_t)offset, buf, length);}
Exemplo n.º 22
0
/*
 * function to extract fat archives
 */
uint8_t 
extract_fat(ea_t address, char *outputFilename)
{
#if DEBUG
    msg("[DEBUG] Trying to extract a fat binary target!\n");
#endif
    struct fat_header fatHeader;
    if(!get_many_bytes(address, &fatHeader, sizeof(struct fat_header)))
    {
        msg("[ERROR] Read bytes failed!\n");
        return 1;
    }
    if(validate_fat(fatHeader, address))
        return 1;
    // for fat binaries things are much easier to dump
    // since the fat_arch struct contains total size of the binary :-)
    // open output file
    FILE *outputFile = qfopen(outputFilename, "wb+");
    if (outputFile == NULL)
    {
        msg("[ERROR] Could not open %s file!\n", outputFilename);
        return 1;
    }
    // write fat_header
    qfwrite(outputFile, &fatHeader, sizeof(struct fat_header));
    // read fat_arch
    ea_t fatArchAddress = address + sizeof(struct fat_header);
    uint32_t fatArchSize = sizeof(struct fat_arch)*ntohl(fatHeader.nfat_arch);
    // write all fat_arch structs
    void *fatArchBuf = qalloc(fatArchSize);
    if(!get_many_bytes(fatArchAddress, fatArchBuf, fatArchSize))
    {
        msg("[ERROR] Read bytes failed!\n");
        return 1;
    }
    qfwrite(outputFile, fatArchBuf, fatArchSize);
    qfree(fatArchBuf);
    // write the mach-o binaries inside the fat archive
    for (uint32_t i = 0; i < ntohl(fatHeader.nfat_arch) ; i++)
    {
        struct fat_arch tempFatArch;
        // read the fat_arch struct
        if(!get_many_bytes(fatArchAddress, &tempFatArch, sizeof(struct fat_arch)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
        // read and write the mach-o binary pointed by each fat_arch struct
        void *tempBuf = qalloc(ntohl(tempFatArch.size));
        if(!get_many_bytes(address+ntohl(tempFatArch.offset), tempBuf, ntohl(tempFatArch.size)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
        qfseek(outputFile, ntohl(tempFatArch.offset), SEEK_SET);
        qfwrite(outputFile, tempBuf, ntohl(tempFatArch.size));
        qfree(tempBuf);
        // advance to next fat_arch struct
        fatArchAddress += sizeof(struct fat_arch);
    }
    // all done
    qfclose(outputFile);
    return 0;
}
Exemplo n.º 23
0
// 插件可以从plugins.cfg文件中,被传进一个整型参数。
// 当按下不同的热键或者菜单时,您需要一个插件做不同
// 的事情时,这非常有用。
void __stdcall IDAP_run(int arg)
{
	// 插件的实体
	//在LOG中显示一个字符串
	char *lpInBuf = NULL;
	char *lpTmpBuf = NULL;
	char *lpFilePath = NULL;
	char szValue[MAXSTR + 1] = "";
	char szInValue[MAXSTR + 1] = "";
	//	char szTmp[100] = {0};
	int nPatchLogFlags = 1;
	uval_t nAddres = get_screen_ea();
	asize_t nCount = 1;
	USHORT nWriteRadio = 0;		//单选按钮
	USHORT nSerializeRadio = -1;		//单选按钮
	USHORT checkmask = 0;
	asize_t j = 0;
	asize_t i = 0;
	//	qstrncpy(szInValue,"",sizeof(szInValue));

	if(AskUsingForm_c(dialog, szInValue, &nAddres, &nCount, &nWriteRadio, &nSerializeRadio, &checkmask) == 1)
	{
		if(checkmask & 1)
		{
			nAddres = get_screen_ea();
		}
		size_t len = strlen(szInValue);
		for(i = 0; i < len; i++)
		{
			if(szInValue[i] != ' ')
			{
				szValue[j++] = szInValue[i];
			}
		}
		len = strlen(szValue);
		size_t nHexLen = len / 2;
		if(!len)
		{
			if( lpFilePath = askfile_cv(0, "*.*", "OpenPath", 0))
			{
				FILE* handle = fopen(lpFilePath, "rb");
				if(handle == NULL)
				{
					warning("打开文件失败 Error!\n");
					return;
				}
				fseek(handle, 0, SEEK_END);
				nHexLen = ftell(handle);
				fseek(handle, 0, SEEK_SET);
				lpTmpBuf = (char *)malloc(nHexLen + 1);
				memset(lpTmpBuf, 0, nHexLen + 1);
				fread(lpTmpBuf, 1, nHexLen, handle);
				fclose(handle);
				strcpy(szValue, lpFilePath);
			}
			else
			{
				warning("请输入数据");
				return;
			}

		}
		else if(len % 2)
		{
			warning("数据长度不是2的倍数");
			return;
		}
		else
		{
			for(i = 0;i < len;i++)
			{
				if(!isxdigit(szValue[i]))
				{
					warning("数据中含有非16进制值");
					return;
				}
			}
			lpTmpBuf = (char *) malloc(nHexLen * 2 + 1);
			memset(lpTmpBuf, 0, nHexLen * 2 + 1);
			for(i = 0; i < nHexLen; i++)
			{
				sscanf(&szValue[i * 2],"%02x",lpTmpBuf + i);
			}
		}
		if(nSerializeRadio >= 0)
		{
			asize_t nSerializeSize = (nSerializeRadio + 1) * 4;
			asize_t nSerializeCount = nHexLen * nCount / nSerializeSize;
			for(i = 0; i < nSerializeCount; i++)
			{
				reversedbuf((unsigned char*)lpTmpBuf + nSerializeSize *i, nSerializeSize);
			}
		}
		lpInBuf = (char*)malloc(nHexLen * nCount * 2 + 1);
		memset(lpInBuf, 0, nHexLen * nCount * 2 + 1);
		for(i = 0; i < nCount; i++)
		{
			memcpy(lpInBuf + i * nHexLen, lpTmpBuf, nHexLen);
		}
		free(lpTmpBuf);
		msg("==============修补数据库数据==============\n");
		msg("String Value = %s\n",szValue);
#ifdef __EA64__
		msg("Addres:0x%llX  ValueSize = 0x%llX  Index:%d check = %d\n",nAddres, nHexLen, nCount,checkmask);
#else
		msg("Addres:0x%08X  ValueSize = 0x%08X  Index:%d check = %d\n",nAddres, nHexLen, nCount,checkmask);
#endif
		if(!nWriteRadio)
		{
			msg("WriteData \n",nWriteRadio);
		}
		else
		{
			msg("XorWrite Data \n",nWriteRadio);
		}
		if( nHexLen * nCount > 0x100)
		{
			nPatchLogFlags = askyn_c(0, "%s", "是否打印日志!(默认不打印)\n因为数据量过大会影响IDA会假死!\nNo或Cancel表示不打印日志!\n");
		}
		////////////////////	
		uint32 nSum = 0;
		uchar *mem = NULL;
		if(isLoaded(nAddres) && isLoaded(nAddres + nCount *  nHexLen - 1))
		{

			mem = (uchar *)malloc(nCount *  nHexLen + 1);
			if(mem == NULL)
			{
				warning("malloc 函数执行失败!");
				return;
			}
			get_many_bytes(nAddres,mem, nCount *  nHexLen);
			if(nPatchLogFlags > 0)
			{
				msg("原始数据:\n");
				for(i = 0; i < nCount *  nHexLen; i++)
				{	
					msg("%02X", mem[i]);
				}
				msg("\n");
			}

		}
		else
		{
			if(!isLoaded(nAddres))
			{
				warning("数据地址错误: 0x%p",nAddres);
			}
			else
			{
				warning("写入数据长度过大");
			}
			return;
		}
		///////////////////////////
		//		long nValue = 0;
		for(j = 0;j < nCount;j++)
		{
			for(i = 0;i < nHexLen; i++)
			{
				//				memcpy(szTmp,&szInValue[j * len + i * 2],2);
				//sscanf(&szValue[i * 2],"%02x",&nValue);
				if(nWriteRadio == 1)
				{
					lpInBuf[nSum] ^=   mem[nSum];
				}
				mem[nSum++] = lpInBuf[nSum];

			}
		}
		put_many_bytes(nAddres, mem, nSum);
		if(nPatchLogFlags > 0)
		{
			msg("补丁数据:\n");
			for(i = 0; i < nSum; i++)
			{	
				msg("%02X", mem[i]);
			}
			msg("\n");
		}
		refresh_idaview_anyway();		//刷新反汇编窗口
		free(mem);
		free(lpInBuf);

	}
	return;
}
Exemplo n.º 24
0
uint8_t
extract_mhobject(ea_t address, char *outputFilename)
{
    uint32 magicValue = get_long(address);
    
    struct mach_header *mach_header = NULL;
    struct mach_header_64 *mach_header64 = NULL;
    
    uint8_t arch = 0;
    if (magicValue == MH_MAGIC)
    {
#if DEBUG
        msg("[DEBUG] Target is 32bits!\n");
#endif
        mach_header = (struct mach_header *)qalloc(sizeof(struct mach_header));
        // retrieve mach_header contents
        if(!get_many_bytes(address, mach_header, sizeof(struct mach_header)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
    }
    else if (magicValue == MH_MAGIC_64)
    {
#if DEBUG
        msg("[DEBUG] Target is 64bits!\n");
#endif
        mach_header64 = (struct mach_header_64 *)qalloc(sizeof(struct mach_header_64));
        if(!get_many_bytes(address, mach_header64, sizeof(struct mach_header_64)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
        arch = 1;
    }
    
    // open output file
    FILE *outputFile = qfopen(outputFilename, "wb+");
    if (outputFile == NULL)
    {
        msg("[ERROR] Could not open %s file!\n", outputFilename);
        return 1;
    }
    
    /*
     * we need to write 3 distinct blocks of data:
     * 1) the mach_header
     * 2) the load commands
     * 3) the code and data from the LC_SEGMENT/LC_SEGMENT_64 commands
     */
    
    // write the mach_header to the file
    if (arch)
        qfwrite(outputFile, mach_header64, sizeof(struct mach_header_64));
    else
        qfwrite(outputFile, mach_header, sizeof(struct mach_header));
    
    // swap the endianness of some fields if it's powerpc target
    if (magicValue == MH_CIGAM)
    {
        mach_header->ncmds = ntohl(mach_header->ncmds);
        mach_header->sizeofcmds = ntohl(mach_header->sizeofcmds);
    }
    else if (magicValue == MH_CIGAM_64)
    {
        mach_header64->ncmds = ntohl(mach_header64->ncmds);
        mach_header64->sizeofcmds = ntohl(mach_header64->sizeofcmds);
    }

    // read the load commands
    uint32_t ncmds = arch ? mach_header64->ncmds : mach_header->ncmds;
    uint32_t sizeofcmds = arch ? mach_header64->sizeofcmds : mach_header->sizeofcmds;
    uint32_t headerSize = arch ? sizeof(struct mach_header_64) : sizeof(struct mach_header);
    
    uint8_t *loadcmdsBuffer = NULL;
    loadcmdsBuffer = (uint8_t*)qalloc(sizeofcmds);
    
    get_many_bytes(address + headerSize, loadcmdsBuffer, sizeofcmds);
    // write all the load commands block to the output file
    // only LC_SEGMENT commands contain further data
    qfwrite(outputFile, loadcmdsBuffer, sizeofcmds);
    
    // and now process the load commands so we can retrieve code and data
    struct load_command loadCommand;
    ea_t cmdsBaseAddress = address + headerSize;    
    
    // read segments so we can write the code and data
    // only the segment commands have useful information
    for (uint32_t i = 0; i < ncmds; i++)
    {
        get_many_bytes(cmdsBaseAddress, &loadCommand, sizeof(struct load_command));
        struct segment_command segmentCommand;
        struct segment_command_64 segmentCommand64;
        // swap the endianness of some fields if it's powerpc target
        if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64)
        {
            loadCommand.cmd = ntohl(loadCommand.cmd);
            loadCommand.cmdsize = ntohl(loadCommand.cmdsize);
        }

        // 32bits targets
        if (loadCommand.cmd == LC_SEGMENT)
        {
            get_many_bytes(cmdsBaseAddress, &segmentCommand, sizeof(struct segment_command));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM)
            {
                segmentCommand.nsects   = ntohl(segmentCommand.nsects);
                segmentCommand.fileoff  = ntohl(segmentCommand.fileoff);
                segmentCommand.filesize = ntohl(segmentCommand.filesize);
            }

            ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command);
            struct section sectionCommand; 
            // iterate thru all sections to find the first code offset
            // FIXME: we need to find the lowest one since the section info can be reordered
            for (uint32_t x = 0; x < segmentCommand.nsects; x++)
            {
                get_many_bytes(sectionAddress, &sectionCommand, sizeof(struct section));
                // swap the endianness of some fields if it's powerpc target
                if (magicValue == MH_CIGAM)
                {
                    sectionCommand.offset = ntohl(sectionCommand.offset);
                    sectionCommand.nreloc = ntohl(sectionCommand.nreloc);
                    sectionCommand.reloff = ntohl(sectionCommand.reloff);
                }
                if (sectionCommand.nreloc > 0)
                {
                    uint32_t size = sectionCommand.nreloc*sizeof(struct relocation_info);
                    uint8_t *relocBuf = (uint8_t*)qalloc(size);
                    get_many_bytes(address + sectionCommand.reloff, relocBuf, size);
                    qfseek(outputFile, sectionCommand.reloff, SEEK_SET);
                    qfwrite(outputFile, relocBuf, size);
                    qfree(relocBuf);
                }
                sectionAddress += sizeof(struct section);
            }
            // read and write the data
            uint8_t *buf = (uint8_t*)qalloc(segmentCommand.filesize);
            get_many_bytes(address + segmentCommand.fileoff, buf, segmentCommand.filesize);
            // always set the offset
            qfseek(outputFile, segmentCommand.fileoff, SEEK_SET);
            qfwrite(outputFile, buf, segmentCommand.filesize);
            qfree(buf);
        }
        // we need this to dump missing relocations
        else if (loadCommand.cmd == LC_SYMTAB)
        {
            struct symtab_command symtabCommand;
            get_many_bytes(cmdsBaseAddress, &symtabCommand, sizeof(struct symtab_command));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64)
            {
                symtabCommand.nsyms   = ntohl(symtabCommand.nsyms);
                symtabCommand.symoff  = ntohl(symtabCommand.symoff);
                symtabCommand.stroff  = ntohl(symtabCommand.stroff);
                symtabCommand.strsize = ntohl(symtabCommand.strsize);
            }
            
            if (symtabCommand.symoff > 0)
            {
                void *buf = qalloc(symtabCommand.nsyms*sizeof(struct nlist));
                get_many_bytes(address + symtabCommand.symoff, buf, symtabCommand.nsyms*sizeof(struct nlist));
                qfseek(outputFile, symtabCommand.symoff, SEEK_SET);
                qfwrite(outputFile, buf, symtabCommand.nsyms*sizeof(struct nlist));
                qfree(buf);
            }
            if (symtabCommand.stroff > 0)
            {
                void *buf = qalloc(symtabCommand.strsize);
                get_many_bytes(address + symtabCommand.stroff, buf, symtabCommand.strsize);
                qfseek(outputFile, symtabCommand.stroff, SEEK_SET);
                qfwrite(outputFile, buf, symtabCommand.strsize);
                qfree(buf);
            }
        }
        // 64bits targets
        // FIXME: will this work ? needs to be tested :-)
        else if (loadCommand.cmd == LC_SEGMENT_64)
        {
            get_many_bytes(cmdsBaseAddress, &segmentCommand64, sizeof(struct segment_command_64));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM_64)
            {
                segmentCommand64.nsects   = ntohl(segmentCommand64.nsects);
                segmentCommand64.fileoff  = bswap64(segmentCommand64.fileoff);
                segmentCommand64.filesize = bswap64(segmentCommand64.filesize);
            }

            ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command_64);
            struct section_64 sectionCommand64;
            for (uint32_t x = 0; x < segmentCommand64.nsects; x++)
            {
                get_many_bytes(sectionAddress, &sectionCommand64, sizeof(struct section_64));
                // swap the endianness of some fields if it's powerpc target
                if (magicValue == MH_CIGAM_64)
                {
                    sectionCommand64.offset = ntohl(sectionCommand64.offset);
                    sectionCommand64.nreloc = ntohl(sectionCommand64.nreloc);
                    sectionCommand64.reloff = ntohl(sectionCommand64.reloff);
                }
                
                if (sectionCommand64.nreloc > 0)
                {
                    uint32_t size = sectionCommand64.nreloc*sizeof(struct relocation_info);
                    uint8_t *relocBuf = (uint8_t*)qalloc(size);
                    get_many_bytes(address + sectionCommand64.reloff, relocBuf, size);
                    qfseek(outputFile, sectionCommand64.reloff, SEEK_SET);
                    qfwrite(outputFile, relocBuf, size);
                    qfree(relocBuf);
                }
                sectionAddress += sizeof(struct section_64);
            }
            // read and write the data
            uint8_t *buf = (uint8_t*)qalloc(segmentCommand64.filesize);
            get_many_bytes(address + segmentCommand64.fileoff, buf, segmentCommand64.filesize);
            qfseek(outputFile, segmentCommand64.fileoff, SEEK_SET);
            qfwrite(outputFile, buf, segmentCommand64.filesize);
            qfree(buf);
        }
        cmdsBaseAddress += loadCommand.cmdsize;
    }
    
    // all done, close file and free remaining buffers!
    qfclose(outputFile);
    qfree(mach_header);
    qfree(mach_header64);
    qfree(loadcmdsBuffer);
    return 0;
    
}
Exemplo n.º 25
0
/*
 * function to extract non-fat binaries, 32 and 64bits
 */
uint8_t 
extract_macho(ea_t address, char *outputFilename)
{
    uint32 magicValue = get_long(address);
    
    struct mach_header *mach_header = NULL;
    struct mach_header_64 *mach_header64 = NULL;
    
    uint8_t arch = 0;
    if (magicValue == MH_MAGIC || magicValue == MH_CIGAM)
    {
#if DEBUG
        msg("[DEBUG] Target is 32bits!\n");
#endif
        mach_header = (struct mach_header *)qalloc(sizeof(struct mach_header));
        // retrieve mach_header contents
        if(!get_many_bytes(address, mach_header, sizeof(struct mach_header)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
    }
    else if (magicValue == MH_MAGIC_64 || magicValue == MH_CIGAM_64)
    {
#if DEBUG
        msg("[DEBUG] Target is 64bits!\n");
#endif
        mach_header64 = (struct mach_header_64 *)qalloc(sizeof(struct mach_header_64));
        if(!get_many_bytes(address, mach_header64, sizeof(struct mach_header_64)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
        arch = 1;
    }
    else
    {
        msg("[ERROR] Unknown target!\n");
        return 1;
    }
    
    // open output file
    FILE *outputFile = qfopen(outputFilename, "wb+");
    if (outputFile == NULL)
    {
        msg("[ERROR] Could not open %s file!\n", outputFilename);
        return 1;
    }
    
    /*
     * we need to write 3 distinct blocks of data:
     * 1) the mach_header
     * 2) the load commands
     * 3) the code and data from the LC_SEGMENT/LC_SEGMENT_64 commands
     */
    
    // write the mach_header to the file
    if (arch)
        qfwrite(outputFile, mach_header64, sizeof(struct mach_header_64));
    else
        qfwrite(outputFile, mach_header, sizeof(struct mach_header));
    
    // swap the endianness of some fields if it's powerpc target
    if (magicValue == MH_CIGAM)
    {
        mach_header->ncmds = ntohl(mach_header->ncmds);
        mach_header->sizeofcmds = ntohl(mach_header->sizeofcmds);
    }
    else if (magicValue == MH_CIGAM_64)
    {
        mach_header64->ncmds = ntohl(mach_header64->ncmds);
        mach_header64->sizeofcmds = ntohl(mach_header64->sizeofcmds);
    }
    
    // read the load commands
    uint32_t ncmds      = arch ? mach_header64->ncmds : mach_header->ncmds;
    uint32_t sizeofcmds = arch ? mach_header64->sizeofcmds : mach_header->sizeofcmds;
    uint32_t headerSize = arch ? sizeof(struct mach_header_64) : sizeof(struct mach_header);
    
    uint8_t *loadcmdsBuffer = NULL;
    loadcmdsBuffer = (uint8_t*)qalloc(sizeofcmds);
    
    get_many_bytes(address + headerSize, loadcmdsBuffer, sizeofcmds);
    // write all the load commands block to the output file
    // only LC_SEGMENT commands contain further data
    qfwrite(outputFile, loadcmdsBuffer, sizeofcmds);
    
    // and now process the load commands so we can retrieve code and data
    struct load_command loadCommand;
    ea_t cmdsBaseAddress = address + headerSize;    
    ea_t codeOffset = 0;
    
    // read segments so we can write the code and data
    // only the segment commands have useful information
    for (uint32_t i = 0; i < ncmds; i++)
    {
        get_many_bytes(cmdsBaseAddress, &loadCommand, sizeof(struct load_command));
        struct segment_command segmentCommand;
        struct segment_command_64 segmentCommand64;
        // swap the endianness of some fields if it's powerpc target
        if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64)
        {
            loadCommand.cmd     = ntohl(loadCommand.cmd);
            loadCommand.cmdsize = ntohl(loadCommand.cmdsize);
        }
        
        // 32bits targets
        // FIXME: do we also need to dump the relocs info here ?
        if (loadCommand.cmd == LC_SEGMENT)
        {
            get_many_bytes(cmdsBaseAddress, &segmentCommand, sizeof(struct segment_command));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM)
            {
                segmentCommand.nsects   = ntohl(segmentCommand.nsects);
                segmentCommand.fileoff  = ntohl(segmentCommand.fileoff);
                segmentCommand.filesize = ntohl(segmentCommand.filesize);
            }
            // the file offset info in LC_SEGMENT is zero at __TEXT so we need to get it from the sections
            // the size is ok to be used
            if (strncmp(segmentCommand.segname, "__TEXT", 16) == 0)
            {
                ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command);
                struct section sectionCommand; 
                // iterate thru all sections to find the first code offset
                // FIXME: we need to find the lowest one since the section info can be reordered
                for (uint32_t x = 0; x < segmentCommand.nsects; x++)
                {
                    get_many_bytes(sectionAddress, &sectionCommand, sizeof(struct section));
                    // swap the endianness of some fields if it's powerpc target
                    if (magicValue == MH_CIGAM)
                        sectionCommand.offset = ntohl(sectionCommand.offset);
                    
                    if (strncmp(sectionCommand.sectname, "__text", 16) == 0)
                    {
                        codeOffset = sectionCommand.offset;
                        break;
                    }
                    sectionAddress += sizeof(struct section);
                }
            }
            // for all other segments the fileoffset info in the LC_SEGMENT is valid so we can use it
            else
            {
                codeOffset = segmentCommand.fileoff;
            }
            // read and write the data
            uint8_t *buf = (uint8_t*)qalloc(segmentCommand.filesize);
            get_many_bytes(address + codeOffset, buf, segmentCommand.filesize);
            // always set the offset
            qfseek(outputFile, codeOffset, SEEK_SET);
            qfwrite(outputFile, buf, segmentCommand.filesize);
            qfree(buf);
        }
        // 64bits targets
        else if (loadCommand.cmd == LC_SEGMENT_64)
        {
            get_many_bytes(cmdsBaseAddress, &segmentCommand64, sizeof(struct segment_command_64));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM_64)
            {
                segmentCommand64.nsects   = ntohl(segmentCommand64.nsects);
                segmentCommand64.fileoff  = bswap64(segmentCommand64.fileoff);
                segmentCommand64.filesize = bswap64(segmentCommand64.filesize);
            }

            if(strncmp(segmentCommand64.segname, "__TEXT", 16) == 0)
            {
                ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command_64);
                struct section_64 sectionCommand64;
                for (uint32_t x = 0; x < segmentCommand64.nsects; x++)
                {
                    get_many_bytes(sectionAddress, &sectionCommand64, sizeof(struct section_64));
                    // swap the endianness of some fields if it's powerpc target
                    if (magicValue == MH_CIGAM_64)
                        sectionCommand64.offset = ntohl(sectionCommand64.offset);

                    if (strncmp(sectionCommand64.sectname, "__text", 16) == 0)
                    {
                        codeOffset = sectionCommand64.offset;
                        break;
                    }
                    sectionAddress += sizeof(struct section_64);
                }
            }
            else
            {
                codeOffset = segmentCommand64.fileoff;
            }
            // read and write the data
            uint8_t *buf = (uint8_t*)qalloc(segmentCommand64.filesize);
            get_many_bytes(address + codeOffset, buf, segmentCommand64.filesize);
            qfseek(outputFile, codeOffset, SEEK_SET);
            qfwrite(outputFile, buf, segmentCommand64.filesize);
            qfree(buf);
        }
        cmdsBaseAddress += loadCommand.cmdsize;
    }
    
    // all done, close file and free remaining buffers!
    qfclose(outputFile);
    qfree(mach_header);
    qfree(mach_header64);
    qfree(loadcmdsBuffer);
    return 0;
}
Exemplo n.º 26
0
static bool extractEntry(uint32 off, int level, bool named)
{
    IMAGE_RESOURCE_DIRECTORY_ENTRY  rde;

    if ( off + sizeof(rde) >= ResTop )
        return false;
    if ( !get_many_bytes(ResBase + off, &rde, sizeof(rde)) )
        return false;

    if ( (bool)rde.NameIsString != named )
        return false;

    if ( (bool)rde.DataIsDirectory != (level != 2) )
        return false;

    off += sizeof(rde);

    if ( !named )
    {
        Names[level].Id = rde.Id;
    }
    else
    {
        ea_t npos = rde.NameOffset;
        if( npos < off || npos + 2 >= ResTop )
            return false;
        uint32 nlen = get_word(npos + ResBase)*sizeof(wchar_t);
        if ( !nlen || npos + nlen > ResTop )
            return false;
        wchar_t *p = (wchar_t *)qalloc(nlen + sizeof(wchar_t));
        if ( p == NULL )
        {
            msg("Not enough memory for resource names\n");
            return false;
        }
        if ( !get_many_bytes(npos + sizeof(uint16) + ResBase, p, nlen) )
        {
bad_name:
            qfree(p);
            return false;
        }
        p[nlen/sizeof(wchar_t)] = 0;
        size_t wlen = wcslen(p);
        if ( !wlen || wlen < nlen/2-1 ) goto bad_name;
        Names[level].name = p;
        Names[level].len = uint32((wlen+1)*sizeof(wchar_t));
    }

    if ( level != 2 )
    {
        bool res = false;
        if ( rde.OffsetToDirectory >= off )
            res = extractDirectory(rde.OffsetToDirectory, level+1);

        if ( Names[level].len ) qfree(Names[level].name);
        Names[level].name = NULL;
        Names[level].len  = 0;
        return res;
    }

    if ( rde.OffsetToData < off )
        return false;

    return extractData(rde.OffsetToData);
}