add mentohust from KyleRicardo

This commit is contained in:
sbwml 2023-02-17 17:00:28 +08:00
parent d2c3f1d7ef
commit 511de31f9d
20 changed files with 19851 additions and 0 deletions

54
mentohust/Makefile Normal file
View File

@ -0,0 +1,54 @@
#
# Copyright (C) 2014-2015 KyleRicardo
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=mentohust
PKG_VERSION:=0.3.1
PKG_RELEASE:=1
PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
define Package/mentohust
SECTION:=net
CATEGORY:=Network
DEPENDS:=+libpcap
TITLE:=A Ruijie Client Daemon
URL:=https://github.com/KyleRicardo/MentoHUST-OpenWrt-ipk.git
SUBMENU:=Ruijie
endef
define Package/mentohust/description
A Ruijie Client Daemon,
Most usually used in Chinese universities.
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
$(SED) 's/dhclient/udhcpc -i/g' $(PKG_BUILD_DIR)/myconfig.c
endef
define Build/Compile
#$(Build/Compile/$(PKG_NAME))
$(MAKE) -C $(PKG_BUILD_DIR)/ \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS)" \
CPPFLAGS="$(TARGET_CPPFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS) -ldl"
endef
define Package/mentohust/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mentohust $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

46
mentohust/src/Makefile Normal file
View File

@ -0,0 +1,46 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/package.mk
CC = mips-openwrt-linux-gcc
CFLAGS = -Wall -g -O2
INC_DIR= $(STAGING_DIR)/usr/include
LINK_DIR= $(STAGING_DIR)/usr/lib
LIBS= -lpcap
OBJ = mentohust.o dlfunc.o md5.o mycheck.o myconfig.o myfunc.o strnormalize.o myini.o mystate.o
.PHONY: all
all: mentohust
mentohust: $(OBJ)
$(CC) $(CFLAGS) -o $@ $(OBJ) $(LIBS) -I$(INC_DIR) -L$(LINK_DIR) $(LDFLAGS)
mentohust.o : mentohust.c
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
dlfunc.o : dlfunc.c
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
md5.o : md5.c md5.h
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
strnormalize.o: strnormalize.c strnormalize.h
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
mycheck.o : mycheck.c
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
myconfig.o : myconfig.c
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
myfunc.o : myfunc.c
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
myini.o : myini.c
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
mystate.o : mystate.c
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
clean :
rm -v $(OBJ) mentohust

153
mentohust/src/dlfunc.c Normal file
View File

@ -0,0 +1,153 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* dlfunc.c
*
* HustMoon@BYHH
* www.ehust@gmail.com
* 2009.11.11
*/
#include "dlfunc.h"
#ifndef NO_DYLOAD
#include <dlfcn.h>
int (*pcap_findalldevs)(pcap_if_t **, char *);
void (*pcap_freealldevs)(pcap_if_t *);
pcap_t *(*pcap_open_live)(const char *, int, int, int, char *);
int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
int (*pcap_setfilter)(pcap_t *, struct bpf_program *);
char *(*pcap_geterr)(pcap_t *);
void (*pcap_freecode)(struct bpf_program *);
int (*pcap_loop)(pcap_t *, int, pcap_handler, unsigned char *);
void (*pcap_close)(pcap_t *);
void (*pcap_breakloop)(pcap_t *);
int (*pcap_sendpacket)(pcap_t *, const unsigned char *, int);
static void *libpcap = NULL;
int load_libpcap(void) {
char *error;
#ifdef MAC_OS
char *file[] = {"libpcap.dylib", "libpcap.A.dylib"};
int i, count = 2;
#else
char *file[] = {"libpcap.so", "libpcap.so.1", "libpcap.so.1.0", "libpcap.so.0.9", "libpcap.so.0.8"};
int i, count = 5;
#endif
for (i=0; i<count && !libpcap; i++) {
libpcap = dlopen(file[i], RTLD_LAZY);
error = dlerror();
}
if (libpcap == NULL) {
printf("!! 打开libpcap失败请检查是否已安装该库文件。\n");
return -1;
}
if ((pcap_findalldevs = dlsym(libpcap, "pcap_findalldevs"), error = dlerror()) != NULL
|| (pcap_freealldevs = dlsym(libpcap, "pcap_freealldevs"), error = dlerror()) != NULL
|| (pcap_open_live = dlsym(libpcap, "pcap_open_live"), error = dlerror()) != NULL
|| (pcap_compile = dlsym(libpcap, "pcap_compile"), error = dlerror()) != NULL
|| (pcap_setfilter = dlsym(libpcap, "pcap_setfilter"), error = dlerror()) != NULL
|| (pcap_geterr = dlsym(libpcap, "pcap_geterr"), error = dlerror()) != NULL
|| (pcap_freecode = dlsym(libpcap, "pcap_freecode"), error = dlerror()) != NULL
|| (pcap_loop = dlsym(libpcap, "pcap_loop"), error = dlerror()) != NULL
|| (pcap_close = dlsym(libpcap, "pcap_close"), error = dlerror()) != NULL
|| (pcap_breakloop = dlsym(libpcap, "pcap_breakloop"), error = dlerror()) != NULL
|| (pcap_sendpacket = dlsym(libpcap, "pcap_sendpacket"), error = dlerror()) != NULL) {
printf("!! 从libpcap获取函数失败: %s\n", error);
free_libpcap();
return -1;
}
return 0;
}
void free_libpcap(void) {
if (libpcap) {
dlclose(libpcap);
dlerror();
libpcap = NULL;
}
}
#endif /* NO_DYLOAD */
#ifndef NO_NOTIFY
#include <dlfcn.h>
typedef void NotifyNotification, GtkWidget, GError;
typedef char gchar;
typedef int gint, gboolean;
static gboolean (*notify_notification_update)(NotifyNotification *, const gchar *,
const gchar *, const gchar *);
static void (*notify_notification_set_timeout)(NotifyNotification *, gint);
static gboolean (*notify_notification_show)(NotifyNotification *, GError **);
static void *libnotify = NULL;
static NotifyNotification *notify = NULL;
int load_libnotify(void) {
char *error;
gboolean (*notify_init)(const char *);
NotifyNotification *(*notify_notification_new)(const gchar *, const gchar *,
const gchar *, GtkWidget *);
#ifdef MAC_OS
char *file[] = {"libnotify.dylib", "libnotify.1.dylib"};
int i, count = 2;
#else
char *file[] = {"libnotify.so", "libnotify.so.1"};
int i, count = 2;
#endif
for (i=0; i<count && !libnotify; i++) {
libnotify = dlopen(file[i], RTLD_LAZY);
error = dlerror();
}
if (libnotify == NULL) {
printf("!! 打开libnotify失败请检查是否已安装该库文件。\n");
return -1;
}
if ((notify_init = dlsym(libnotify, "notify_init"), error = dlerror()) != NULL
|| (notify_notification_new = dlsym(libnotify, "notify_notification_new"), error = dlerror()) != NULL
|| (notify_notification_show = dlsym(libnotify, "notify_notification_show"), error = dlerror()) != NULL
|| (notify_notification_update = dlsym(libnotify, "notify_notification_update"), error = dlerror()) != NULL
|| (notify_notification_set_timeout = dlsym(libnotify, "notify_notification_set_timeout"), error = dlerror()) != NULL) {
printf("!! 从libnotify获取函数失败: %s\n", error);
free_libnotify();
return -1;
}
if (!notify_init("mentohust")) {
printf("!! 初始化libnotify失败。\n");
free_libnotify();
return -1;
}
notify = notify_notification_new("MentoHUST", NULL, NULL, NULL);
return 0;
}
void free_libnotify(void) {
void (*notify_uninit)(void);
if (notify) {
notify_uninit = dlsym(libnotify, "notify_uninit");
if (!dlerror())
notify_uninit();
notify = NULL;
}
if (libnotify) {
dlclose(libnotify);
dlerror();
libnotify = NULL;
}
}
void set_timeout(int timeout) {
notify_notification_set_timeout(notify, timeout);
}
void show_notify(const char *summary, char *body) {
notify_notification_update(notify, summary, body, NULL);
notify_notification_show(notify, NULL);
}
#endif /* NO_NOTIFY */

77
mentohust/src/dlfunc.h Normal file
View File

@ -0,0 +1,77 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* dlfunc.h
*
*/
#ifndef HUSTMOON_DLFUNC_H
#define HUSTMOON_DLFUNC_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <sys/time.h>
#define PCAP_ERRBUF_SIZE 256
#define PCAP_IF_LOOPBACK 0x00000001
typedef unsigned int bpf_u_int32;
typedef void pcap_t;
typedef struct pcap_if {
struct pcap_if *next;
char *name;
char *description;
void *addresses;
bpf_u_int32 flags;
}pcap_if_t;
struct bpf_program {
unsigned int bf_len;
void *bf_insns;
};
struct pcap_pkthdr {
struct timeval ts;
bpf_u_int32 caplen;
bpf_u_int32 len;
};
typedef void (*pcap_handler)(unsigned char *, const struct pcap_pkthdr *, const unsigned char *);
#ifdef NO_DYLOAD
int pcap_findalldevs(pcap_if_t **, char *);
void pcap_freealldevs(pcap_if_t *);
pcap_t *pcap_open_live(const char *, int, int, int, char *);
int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
int pcap_setfilter(pcap_t *, struct bpf_program *);
char *pcap_geterr(pcap_t *);
void pcap_freecode(struct bpf_program *);
int pcap_loop(pcap_t *, int, pcap_handler, unsigned char *);
void pcap_close(pcap_t *);
void pcap_breakloop(pcap_t *);
int pcap_sendpacket(pcap_t *, const unsigned char *, int);
#else
extern int (*pcap_findalldevs)(pcap_if_t **, char *);
extern void (*pcap_freealldevs)(pcap_if_t *);
extern pcap_t *(*pcap_open_live)(const char *, int, int, int, char *);
extern int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
extern int (*pcap_setfilter)(pcap_t *, struct bpf_program *);
extern char *(*pcap_geterr)(pcap_t *);
extern void (*pcap_freecode)(struct bpf_program *);
extern int (*pcap_loop)(pcap_t *, int, pcap_handler, unsigned char *);
extern void (*pcap_close)(pcap_t *);
extern void (*pcap_breakloop)(pcap_t *);
extern int (*pcap_sendpacket)(pcap_t *, const unsigned char *, int);
int load_libpcap(void); /* 载入libpcap.so */
void free_libpcap(void); /* 释放libpcap.so */
#endif /* NO_DYLOAD */
#ifndef NO_NOTIFY
int load_libnotify(void); /* 载入libnotify.so */
void free_libnotify(void); /* 释放libnotify.so */
void set_timeout(int timeout); /* 设置超时间隔 */
void show_notify(const char *summary, char *body); /* 显示通知:概要、正文 */
#endif /* NO_NOTIFY */
#endif /* HUSTMOON_DLFUNC_H */

297
mentohust/src/md5.c Normal file
View File

@ -0,0 +1,297 @@
/* MD5.c - an implementation of md5 algorithm */
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
#include <string.h>
/* Constants for MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform(UINT4 [4], UCHAR [64]);
static void Encode(UCHAR *, UINT4 *, UINT4);
static void Decode(UINT4 *, UCHAR *, UINT4);
static UCHAR PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (MD5_CTX * context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (MD5_CTX *context, UCHAR *input, UINT4 inputLen)
{
UINT4 i, index, partLen;
/* Compute number of bytes mod 64 */
index = (UINT4)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (UCHAR digest[16], MD5_CTX *context)
{
UCHAR bits[8];
UINT4 index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (UINT4)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (UINT4 state[4],UCHAR block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (UCHAR). Assumes len is
a multiple of 4.
*/
static void Encode (UCHAR *output, UINT4 *input, UINT4 len)
{
UINT4 i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (UCHAR)(input[i] & 0xff);
output[j+1] = (UCHAR)((input[i] >> 8) & 0xff);
output[j+2] = (UCHAR)((input[i] >> 16) & 0xff);
output[j+3] = (UCHAR)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (UCHAR) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (UINT4 *output, UCHAR *input, UINT4 len)
{
UINT4 i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/*Compute the md5sum (return static-local-variable),whose length is 16 bytes.*/
UCHAR* ComputeHash(UCHAR* src, UINT4 len)
{
MD5_CTX context;
static UCHAR digest[16];
MD5Init(&context);
MD5Update(&context, src, len);
MD5Final(digest, &context);
return digest;
}

43
mentohust/src/md5.h Normal file
View File

@ -0,0 +1,43 @@
/* MD5.H - header file for MD5.C */
/*
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.*/
#ifndef MD5_H
#define MD5_H
#include "types.h"
/* MD5 context. */
typedef struct
{
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
UCHAR buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init(MD5_CTX * context);
void MD5Update(MD5_CTX *context, UCHAR *input, UINT4 inputLen);
void MD5Final(UCHAR digest[16], MD5_CTX *context);
UCHAR* ComputeHash(UCHAR *src, UINT4 len);
#endif /* MD5_H */

278
mentohust/src/mentohust.c Normal file
View File

@ -0,0 +1,278 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* mentohust.c
* MentoHUST主函数
* HustMoon@BYHH
* www.ehust@gmail.com
*/
#include "strnormalize.h"
#include "myconfig.h"
#include "mystate.h"
#include "myfunc.h"
#include "dlfunc.h"
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <unistd.h>
extern pcap_t *hPcap;
extern volatile int state;
extern u_char *fillBuf;
extern const u_char *capBuf;
extern unsigned startMode, dhcpMode, maxFail;
extern u_char destMAC[];
extern int lockfd;
#ifndef NO_NOTIFY
extern int showNotify;
#endif
#ifndef NO_ARP
extern u_int32_t rip, gateway;
extern u_char gateMAC[];
#endif
static void exit_handle(void); /* 退出回调 */
static void sig_handle(int sig); /* 信号回调 */
static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf); /* pcap_loop回调 */
static void showRuijieMsg(const u_char *buf, unsigned bufLen); /* 显示锐捷服务器提示信息 */
static void showCernetMsg(const u_char *buf); /* 显示赛尔服务器提示信息 */
int main(int argc, char **argv)
{
atexit(exit_handle);
initConfig(argc, argv);
signal(SIGALRM, sig_handle); /* 定时器 */
signal(SIGHUP, sig_handle); /* 注销时 */
signal(SIGINT, sig_handle); /* Ctrl+C */
signal(SIGQUIT, sig_handle); /* Ctrl+\ */
signal(SIGTSTP, sig_handle); /* Ctrl+Z */
signal(SIGTERM, sig_handle); /* 被结束时 */
if (dhcpMode == 3) /* 认证前DHCP */
switchState(ID_DHCP);
else
switchState(ID_START); /* 开始认证 */
if (-1 == pcap_loop(hPcap, -1, pcap_handle, NULL)) { /* 开始捕获数据包 */
printf("!! 捕获数据包失败,请检查网络连接!\n");
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 错误提示", "捕获数据包失败,请检查网络连接!");
#endif
}
exit(EXIT_FAILURE);
}
static void exit_handle(void)
{
if (state != ID_DISCONNECT)
switchState(ID_DISCONNECT);
if (hPcap != NULL)
pcap_close(hPcap);
if (fillBuf != NULL)
free(fillBuf);
if (lockfd > -1)
close(lockfd);
#ifndef NO_NOTIFY
free_libnotify();
#endif
#ifndef NO_DYLOAD
free_libpcap();
#endif
printf(">> 认证已退出。\n");
}
static void sig_handle(int sig)
{
if (sig == SIGALRM) /* 定时器 */
{
if (-1 == switchState(state))
{
pcap_breakloop(hPcap);
printf("!! 发送数据包失败, 请检查网络连接!\n");
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 错误提示", "发送数据包失败, 请检查网络连接!");
#endif
exit(EXIT_FAILURE);
}
}
else /* 退出 */
{
pcap_breakloop(hPcap);
exit(EXIT_SUCCESS);
}
}
static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf)
{
static unsigned failCount = 0;
#ifndef NO_ARP
if (buf[0x0c]==0x88 && buf[0x0d]==0x8e) {
#endif
if (memcmp(destMAC, buf+6, 6)!=0 && startMode>2) /* 服务器MAC地址不符 */
return;
capBuf = buf;
if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x01) { /* 验证用户名 */
if (startMode < 3) {
memcpy(destMAC, buf+6, 6);
printf("** 认证MAC:\t%s\n", formatHex(destMAC, 6));
startMode += 3; /* 标记为已获取 */
}
if (startMode==3 && memcmp(buf+0x17, "User name", 9)==0) /* 塞尔 */
startMode = 5;
switchState(ID_IDENTITY);
}
else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x04) /* 验证密码 */
switchState(ID_CHALLENGE);
else if (buf[0x0F]==0x00 && buf[0x12]==0x03) { /* 认证成功 */
printf(">> 认证成功!\n");
failCount = 0;
if (!(startMode%3 == 2)) {
getEchoKey(buf);
showRuijieMsg(buf, h->caplen);
}
if (dhcpMode==1 || dhcpMode==2) /* 二次认证第一次或者认证后 */
switchState(ID_DHCP);
else if (startMode%3 == 2)
switchState(ID_WAITECHO);
else
switchState(ID_ECHO);
}
else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x02) /* 显示赛尔提示信息 */
showCernetMsg(buf);
else if (buf[0x0F] == 0x05) /* (赛尔)响应在线 */
switchState(ID_ECHO);
else if (buf[0x0F]==0x00 && buf[0x12]==0x04) { /* 认证失败或被踢下线 */
if (state==ID_WAITECHO || state==ID_ECHO) {
printf(">> 认证掉线,开始重连!\n");
switchState(ID_START);
}
else if (buf[0x1b]!=0 || startMode%3==2) {
printf(">> 认证失败!\n");
if (startMode%3 != 2)
showRuijieMsg(buf, h->caplen);
if (maxFail && ++failCount>=maxFail) {
printf(">> 连续认证失败%u次退出认证。\n", maxFail);
exit(EXIT_SUCCESS);
}
restart();
}
else
switchState(ID_START);
}
#ifndef NO_ARP
} else if (gateMAC[0]!=0xFE && buf[0x0c]==0x08 && buf[0x0d]==0x06) {
if (*(u_int32_t *)(buf+0x1c) == gateway) {
char str[50];
if (gateMAC[0] == 0xFF) {
memcpy(gateMAC, buf+0x16, 6);
printf("** 网关MAC:\t%s\n", formatHex(gateMAC, 6));
fflush(stdout);
sprintf(str, "arp -s %s %s", formatIP(gateway), formatHex(gateMAC, 6));
system(str);
} else if (buf[0x15]==0x02 && *(u_int32_t *)(buf+0x26)==rip
&& memcmp(gateMAC, buf+0x16, 6)!=0) {
printf("** ARP欺骗:\t%s\n", formatHex(buf+0x16, 6));
fflush(stdout);
#ifndef NO_NOTIFY
if (showNotify) {
sprintf(str, "欺骗源: %s", formatHex(buf+0x16, 6));
show_notify("MentoHUST - ARP提示", str);
}
#endif
}
}
}
#endif
}
#ifndef MAC_OS
static char *gbk2utf(char *gbksrc, size_t gbklen) /* GBK转UTF8 */
#else
static char *gbk2utf(const char *gbksrc, size_t gbklen) /* GBK转UTF8 */
#endif
{
/* GBK一汉字俩字节UTF-8一汉字3字节二者ASCII字符均一字节
*/
str_normalize_init();
size_t utf8len = gbklen * 3 + 1;
char *utf8dst = (char *)malloc(utf8len);
memset(utf8dst,0,utf8len);
char *temp=(char *)malloc(gbklen+5);
memset(temp, 0, gbklen+5);
memcpy(temp,gbksrc,gbklen);
gbksrc = temp;
gbklen = strlen(gbksrc);
gbk_to_utf8(gbksrc, gbklen, &utf8dst, &utf8len);
free(temp);
return utf8dst;
}
static void showRuijieMsg(const u_char *buf, unsigned bufLen)
{
char *serverMsg;
int length = buf[0x1b];
if (length > 0)
{
for (serverMsg=(char *)(buf+0x1c); *serverMsg=='\r'||*serverMsg=='\n'; serverMsg++,length--); /* 跳过开头的换行符 */
if (strlen(serverMsg) < length)
length = strlen(serverMsg);
if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
{
printf("$$ 系统提示:\t%s\n", serverMsg);
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 系统提示", serverMsg);
#endif
free(serverMsg);
}
}
if ((length=0x1c+buf[0x1b]+0x69+39) < bufLen)
{
serverMsg=(char *)(buf+length);
if (buf[length-1]-2 > bufLen-length)
length = bufLen - length;
else
length = buf[length-1]-2;
for (; *serverMsg=='\r'||*serverMsg=='\n'; serverMsg++,length--);
if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
{
printf("$$ 计费提示:\t%s\n", serverMsg);
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 计费提示", serverMsg);
#endif
free(serverMsg);
}
}
fflush(stdout);
}
static void showCernetMsg(const u_char *buf)
{
char *serverMsg = (char *)(buf+0x17);
int length = ntohs(*(u_int16_t *)(buf+0x14)) - 5;
if (strlen(serverMsg) < length)
length = strlen(serverMsg);
if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
{
printf("$$ 系统提示:\t%s\n", serverMsg);
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 系统提示", serverMsg);
#endif
free(serverMsg);
}
fflush(stdout);
}

189
mentohust/src/mycheck.c Normal file
View File

@ -0,0 +1,189 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* mycheck.c
*
* kkHAIKE & HustMoon
*/
#include "mycheck.h"
#include "md5.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static BYTE *bin_8021x = NULL;
static DWORD size_8021x;
static BYTE hex[][17]={"0123456789ABCDEF", "0123456789abcdef"};
#ifdef WORDS_BIGENDIAN
WORD ltobs(WORD x) {
return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);
}
DWORD ltobl(DWORD x) {
return ((x & 0xff) << 24) |\
((x & 0xff00) << 8) |\
((x & 0xff0000) >> 8) |\
((x & 0xff000000) >> 24);
}
#endif
void hex_to_str(const BYTE *a, char *b, int hexsize, int upper) {
BYTE *q = (BYTE *)b;
int i;
for (i=0; i<hexsize; i++) {
*q = hex[upper][a[i]>>4]; q++;
*q = hex[upper][a[i]&0xf]; q++;
}
*q = 0;
}
BYTE *ReadCode(const char *file, DWORD *size) {
BYTE *data = NULL;
int i;
FILE *fp;
PPE_HEADER_MAP hpe;
if ((fp=fopen(file, "rb")) == NULL)
goto fileError;
data = (BYTE *)malloc(0x1000);
if (fread(data, 0x1000, 1, fp) < 1)
goto fileError;
hpe = (PPE_HEADER_MAP)(data + LTOBL(((PIMAGE_DOS_HEADER)data)->e_lfanew));
for (i=0; i<LTOBS(hpe->_head.NumberOfSections); i++) {
if (LTOBL(hpe->section_header[i].Characteristics) & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE)) {
fseek(fp, LTOBL(hpe->section_header[i].PointerToRawData), SEEK_SET);
*size = LTOBL(hpe->section_header[i].SizeOfRawData);
free(data);
data = (BYTE *)malloc(*size);
if (fread(data, *size, 1, fp) < 1)
goto fileError;
fclose(fp);
return data;
}
}
fileError:
if (fp != NULL)
fclose(fp);
if (data != NULL)
free(data);
return NULL;
}
BYTE *ReadCode2(const char *dataFile, DWORD *size) {
BYTE Buf[16], *buf=Buf;
FILE *fp = NULL;
if ((fp=fopen(dataFile, "rb")) == NULL
|| fread(buf, 16, 1, fp ) < 1)
goto fileError;
*size = LTOBL(*(UINT4 *)buf ^ *(UINT4 *)(buf + 4));
if ((int)*size <= 0)
goto fileError;
buf = (BYTE *)malloc(*size+0x100);
if (fread(buf, *size, 1, fp) < 1) {
free(buf);
goto fileError;
}
fclose(fp);
return buf;
fileError:
if (fp != NULL)
fclose(fp);
return NULL;
}
void check_free() {
if (bin_8021x) {
free(bin_8021x);
bin_8021x = NULL;
}
}
int check_init(const char *dataFile) {
char name[0x100];
char *p;
check_free();
strcpy(name, dataFile);
if ((p=strrchr(name, '/')+1) == (void *)1)
p = name;
strcpy(p, "8021x.exe");
if ((bin_8021x=ReadCode(name, &size_8021x)) == NULL
&& (bin_8021x=ReadCode2(dataFile, &size_8021x)) == NULL)
return -1;
return 0;
}
void V2_check(const BYTE *seed, char *final_str) {
int i, size = size_8021x / 8;
BYTE table[144], *md5Dig, *b8021x = (BYTE *)malloc(size+16);
memcpy(b8021x, seed, 16);
for (i=0; i<8; i++) {
memcpy(b8021x+16, bin_8021x+size*i, size);
md5Dig = ComputeHash(b8021x, size+16);
table[18*i] = seed[2*i];
memcpy(table+18*i+1, md5Dig, 16);
table[18*i+17] = seed[2*i+1];
}
free(b8021x);
md5Dig = ComputeHash(table, 144);
hex_to_str(md5Dig, final_str, 16, 1);
}
DWORD getVer(const char *file) {
FILE *fp;
BYTE *data = NULL;
int i, j;
DWORD size, VirtualAddress;
PPE_HEADER_MAP hpe;
PIMAGE_RESOURCE_DIRECTORY prd;
PIMAGE_RESOURCE_DATA_ENTRY prde;
PVS_VERSIONINFO pvs;
if ((fp=fopen(file, "rb")) == NULL)
goto fileError;
data = (BYTE *)malloc(0x1000);
if (fread(data, 0x1000, 1, fp) < 1)
goto fileError;
hpe = (PPE_HEADER_MAP)(data + LTOBL(((PIMAGE_DOS_HEADER)data)->e_lfanew));
for (i=LTOBS(hpe->_head.NumberOfSections)-1; i>=0; i--) {
if (strcmp(hpe->section_header[i].Name, ".rsrc") == 0) {
fseek(fp, LTOBL(hpe->section_header[i].PointerToRawData), SEEK_SET);
size = LTOBL(hpe->section_header[i].SizeOfRawData);
VirtualAddress = LTOBL(hpe->section_header[i].VirtualAddress);
free(data);
data = (BYTE *)malloc(size);
if (fread(data, size, 1, fp) < 1)
goto fileError;
prd = (PIMAGE_RESOURCE_DIRECTORY)data;
for (j=0; j<LTOBS(prd->NumberOfIdEntries); j++) {
prd->DirectoryEntries[j].Name = LTOBL(prd->DirectoryEntries[j].Name);
if (prd->DirectoryEntries[j].Id==16 && prd->DirectoryEntries[j].NameIsString==0) {
prd->DirectoryEntries[j].OffsetToData = LTOBL(prd->DirectoryEntries[j].OffsetToData);
prd = (PIMAGE_RESOURCE_DIRECTORY)(data+prd->DirectoryEntries[j].OffsetToDirectory);
prd->DirectoryEntries[0].OffsetToData = LTOBL(prd->DirectoryEntries[0].OffsetToData);
prd = (PIMAGE_RESOURCE_DIRECTORY)(data+prd->DirectoryEntries[0].OffsetToDirectory);
prde = (PIMAGE_RESOURCE_DATA_ENTRY)(data+LTOBL(prd->DirectoryEntries[0].OffsetToData));
pvs = (PVS_VERSIONINFO)(data+LTOBL(prde->OffsetToData)-VirtualAddress);
size = pvs->Value.dwFileVersionMS;
fclose(fp);
free(data);
return size;
}
}
goto fileError;
}
}
fileError:
if (fp != NULL)
fclose(fp);
if (data != NULL)
free(data);
return -1;
}

219
mentohust/src/mycheck.h Normal file
View File

@ -0,0 +1,219 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* mycheck.h
*
* kkHAIKE
*/
#ifndef MYCHECK_H
#define MYCHECK_H
#include "types.h"
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
//
// NT additional fields.
//
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER {
char Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
typedef struct _PE_HEADER_MAP
{
DWORD signature;
IMAGE_FILE_HEADER _head;
IMAGE_OPTIONAL_HEADER opt_head;
IMAGE_SECTION_HEADER section_header[8];
}PE_HEADER_MAP,*PPE_HEADER_MAP;
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
#ifdef WORDS_BIGENDIAN
union {
struct {
DWORD NameIsString:1;
DWORD NameOffset:31;
};
DWORD Name;
struct {
WORD Id_unuse;
WORD Id;
};
};
union {
DWORD OffsetToData;
struct {
DWORD DataIsDirectory:1;
DWORD OffsetToDirectory:31;
};
};
#else
union {
struct {
DWORD NameOffset:31;
DWORD NameIsString:1;
};
DWORD Name;
WORD Id;
};
union {
DWORD OffsetToData;
struct {
DWORD OffsetToDirectory:31;
DWORD DataIsDirectory:1;
};
};
#endif
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
typedef struct _IMAGE_RESOURCE_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
WORD NumberOfNamedEntries;
WORD NumberOfIdEntries;
IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
DWORD OffsetToData;
DWORD Size;
DWORD CodePage;
DWORD Reserved;
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
typedef struct tagVS_FIXEDFILEINFO {
DWORD dwSignature; /* e.g. 0xfeef04bd */
DWORD dwStrucVersion; /* e.g. 0x00000042 = "0.42" */
DWORD dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
DWORD dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
DWORD dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */
DWORD dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */
DWORD dwFileFlagsMask; /* = 0x3F for version "0.42" */
DWORD dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */
DWORD dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */
DWORD dwFileType; /* e.g. VFT_DRIVER */
DWORD dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */
DWORD dwFileDateMS; /* e.g. 0 */
DWORD dwFileDateLS; /* e.g. 0 */
} VS_FIXEDFILEINFO;
typedef struct _VS_VERSIONINFO {
WORD wLength;
WORD wValueLength;
WORD wType;
WORD szKey[16];
WORD Padding1[1];
VS_FIXEDFILEINFO Value;
} VS_VERSIONINFO, *PVS_VERSIONINFO;
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable
#ifdef WORDS_BIGENDIAN
#define LTOBS(x) ltobs(x)
#define LTOBL(x) ltobl(x)
WORD ltobs(WORD x);
DWORD ltobl(DWORD x);
#else
#define LTOBS(x) (x)
#define LTOBL(x) (x)
#endif
int check_init(const char *dataFile);
void V2_check(const BYTE *seed, char *final_str);
void check_free();
DWORD getVer(const char *file);
#endif

592
mentohust/src/myconfig.c Normal file
View File

@ -0,0 +1,592 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* myconfig.c
*
* HustMoon@BYHH
* www.ehust@gmail.com
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
static const char *VERSION = "0.3.1";
static const char *PACKAGE_BUGREPORT = "http://code.google.com/p/mentohust/issues/list";
#endif
#include "myconfig.h"
#include "myini.h"
#include "myfunc.h"
#include "dlfunc.h"
#include <string.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#define ACCOUNT_SIZE 65 /* 用户名密码长度*/
#define NIC_SIZE 16 /* 网卡名最大长度 */
#define MAX_PATH 255 /* FILENAME_MAX */
#define D_TIMEOUT 8 /* 默认超时间隔 */
#define D_ECHOINTERVAL 30 /* 默认心跳间隔 */
#define D_RESTARTWAIT 15 /* 默认重连间隔 */
#define D_STARTMODE 0 /* 默认组播模式 */
#define D_DHCPMODE 0 /* 默认DHCP模式 */
#define D_DAEMONMODE 0 /* 默认daemon模式 */
#define D_MAXFAIL 0 /* 默认允许失败次数 */
static const char *D_DHCPSCRIPT = "dhclient"; /* 默认DHCP脚本 */
static const char *CFG_FILE = "/etc/mentohust.conf"; /* 配置文件 */
static const char *LOG_FILE = "/tmp/mentohust.log"; /* 日志文件 */
static const char *LOCK_FILE = "/tmp/mentohust.pid"; /* 锁文件 */
#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /* 创建掩码 */
#ifndef NO_NOTIFY
#define D_SHOWNOTIFY 5 /* 默认Show Notify模式 */
int showNotify = D_SHOWNOTIFY; /* 显示通知 */
#endif
extern int bufType; /*0内置xrgsu 1内置Win 2仅文件 3文件+校验*/
extern u_char version[]; /* 版本 */
char userName[ACCOUNT_SIZE] = ""; /* 用户名 */
char password[ACCOUNT_SIZE] = ""; /* 密码 */
char nic[NIC_SIZE] = ""; /* 网卡名 */
char dataFile[MAX_PATH] = ""; /* 数据文件 */
char dhcpScript[MAX_PATH] = ""; /* DHCP脚本 */
u_int32_t ip = 0; /* 本机IP */
u_int32_t mask = 0; /* 子网掩码 */
u_int32_t gateway = 0; /* 网关 */
u_int32_t dns = 0; /* DNS */
u_int32_t pingHost = 0; /* ping */
u_char localMAC[6]; /* 本机MAC */
u_char destMAC[6]; /* 服务器MAC */
unsigned timeout = D_TIMEOUT; /* 超时间隔 */
unsigned echoInterval = D_ECHOINTERVAL; /* 心跳间隔 */
unsigned restartWait = D_RESTARTWAIT; /* 失败等待 */
unsigned startMode = D_STARTMODE; /* 组播模式 */
unsigned dhcpMode = D_DHCPMODE; /* DHCP模式 */
unsigned maxFail = D_MAXFAIL; /* 允许失败次数 */
pcap_t *hPcap = NULL; /* Pcap句柄 */
int lockfd = -1; /* 锁文件描述符 */
static int readFile(int *daemonMode); /* 读取配置文件来初始化 */
static void readArg(char argc, char **argv, int *saveFlag, int *exitFlag, int *daemonMode); /* 读取命令行参数来初始化 */
static void showHelp(const char *fileName); /* 显示帮助信息 */
static int getAdapter(); /* 查找网卡名 */
static void printConfig(); /* 显示初始化后的认证参数 */
static int openPcap(); /* 初始化pcap、设置过滤器 */
static void saveConfig(int daemonMode); /* 保存参数 */
static void checkRunning(int exitFlag, int daemonMode); /* 检测是否已运行 */
#ifndef NO_ENCODE_PASS
static const unsigned char base64Tab[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
static const char xorRuijie[] = {"~!:?$*<(qw2e5o7i8x12c6m67s98w43d2l45we82q3iuu1z4xle23rt4oxclle34e54u6r8m"};
static int encodePass(char *dst, const char *osrc) {
unsigned char in[3], buf[70];
unsigned char *src = buf;
int sz = strlen(osrc);
int i, len;
if (sizeof(xorRuijie) < sz)
return -1;
for(i=0; i<sz; i++)
src[i] = osrc[i] ^ xorRuijie[i];
while (sz > 0) {
for (len=0, i=0; i<3; i++, sz--) {
if (sz > 0) {
len++;
in[i] = src[i];
} else in[i] = 0;
}
src += 3;
if (len) {
dst[0] = base64Tab[ in[0] >> 2 ];
dst[1] = base64Tab[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
dst[2] = len > 1 ? base64Tab[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=';
dst[3] = len > 2 ? base64Tab[ in[2] & 0x3f ] : '=';
dst += 4;
}
}
*dst = '\0';
return 0;
}
static int decodePass(char *dst, const char *src) {
unsigned esi = 0, idx = 0;
int i=0, j=0, equal=0;
for(; src[i]!='\0'; i++) {
if (src[i] == '=') {
if (++equal > 2)
return -1;
} else {
for(idx=0; base64Tab[idx]!='\0'; idx++) {
if(base64Tab[idx] == src[i])
break;
}
if (idx == 64)
return -1;
esi += idx;
}
if(i%4 == 3) {
dst[j++] = (char)(esi>>16);
if(equal < 2)
dst[j++] = (char)(esi>>8);
if(equal < 1)
dst[j++] = (char)esi;
esi = 0;
equal = 0;
}
esi <<= 6;
}
if (i%4!=0 || sizeof(xorRuijie)<j)
return -1;
for(i=0; i<j; i++)
dst[i] ^= xorRuijie[i];
dst[j] = '\0';
return 0;
}
#endif
void initConfig(int argc, char **argv)
{
int saveFlag = 0; /* 是否需要保存参数 */
int exitFlag = 0; /* 0Nothing 1退出 2重启 */
int daemonMode = D_DAEMONMODE; /* 是否后台运行 */
printf("\n欢迎使用MentoHUST\t版本: %s\n"
"Copyright (C) 2009-2010 HustMoon Studio\n"
"人到华中大,有甜亦有辣。明德厚学地,求是创新家。\n"
"Bug report to %s\n\n", VERSION, PACKAGE_BUGREPORT);
saveFlag = (readFile(&daemonMode)==0 ? 0 : 1);
readArg(argc, argv, &saveFlag, &exitFlag, &daemonMode);
#ifndef NO_NOTIFY
if (showNotify) {
seteuid(getuid());
if (load_libnotify() == -1)
showNotify = 0;
else
set_timeout(1000 * showNotify);
seteuid(0);
}
#endif
#ifndef NO_DYLOAD
if (load_libpcap() == -1) {
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 错误提示", "载入libpcap失败, 请检查该库文件!");
#endif
exit(EXIT_FAILURE);
}
#endif
if (nic[0] == '\0')
{
saveFlag = 1;
if (getAdapter() == -1) { /* 找不到(第一块)网卡? */
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 错误提示", "找不到网卡!");
#endif
exit(EXIT_FAILURE);
}
}
if (userName[0]=='\0' || password[0]=='\0') /* 未写用户名密码? */
{
saveFlag = 1;
printf("?? 请输入用户名: ");
scanf("%s", userName);
printf("?? 请输入密码: ");
scanf("%s", password);
printf("?? 请选择组播地址(0标准 1锐捷私有 2赛尔): ");
scanf("%u", &startMode);
startMode %= 3;
printf("?? 请选择DHCP方式(0不使用 1二次认证 2认证后 3认证前): ");
scanf("%u", &dhcpMode);
dhcpMode %= 4;
}
checkRunning(exitFlag, daemonMode);
if (startMode%3==2 && gateway==0) /* 赛尔且未填写网关地址 */
{
gateway = ip; /* 据说赛尔的网关是ip前三字节后一字节是2 */
((u_char *)&gateway)[3] = 0x02;
}
if (dhcpScript[0] == '\0') /* 未填写DHCP脚本 */
strcpy(dhcpScript, D_DHCPSCRIPT);
newBuffer();
printConfig();
if (fillHeader()==-1 || openPcap()==-1) { /* 获取IP、MAC打开网卡 */
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 错误提示", "获取MAC地址或打开网卡失败");
#endif
exit(EXIT_FAILURE);
}
if (saveFlag)
saveConfig(daemonMode);
}
static int readFile(int *daemonMode)
{
char tmp[16];
char *buf = loadFile(CFG_FILE);
if (buf == NULL)
return -1;
getString(buf, "MentoHUST", "Username", "", userName, sizeof(userName));
getString(buf, "MentoHUST", "Password", "", password, sizeof(password));
#ifndef NO_ENCODE_PASS
char pass[ACCOUNT_SIZE*4/3];
if (password[0] == '\0') {
getString(buf, "MentoHUST", "EncodePass", "", pass, sizeof(pass));
decodePass(password, pass);
} else {
encodePass(pass, password);
setString(&buf, "MentoHUST", "Password", NULL);
setString(&buf, "MentoHUST", "EncodePass", pass);
saveFile(buf, CFG_FILE);
}
#endif
getString(buf, "MentoHUST", "Nic", "", nic, sizeof(nic));
getString(buf, "MentoHUST", "Datafile", "", dataFile, sizeof(dataFile));
getString(buf, "MentoHUST", "DhcpScript", "", dhcpScript, sizeof(dhcpScript));
getString(buf, "MentoHUST", "Version", "", tmp, sizeof(tmp));
if (strlen(tmp) >= 3) {
unsigned ver[2];
if (sscanf(tmp, "%u.%u", ver, ver+1)!=EOF && ver[0]!=0) {
version[0] = ver[0];
version[1] = ver[1];
bufType = 1;
}
}
getString(buf, "MentoHUST", "IP", "255.255.255.255", tmp, sizeof(tmp));
ip = inet_addr(tmp);
getString(buf, "MentoHUST", "Mask", "255.255.255.255", tmp, sizeof(tmp));
mask = inet_addr(tmp);
getString(buf, "MentoHUST", "Gateway", "0.0.0.0", tmp, sizeof(tmp));
gateway = inet_addr(tmp);
getString(buf, "MentoHUST", "DNS", "0.0.0.0", tmp, sizeof(tmp));
dns = inet_addr(tmp);
getString(buf, "MentoHUST", "PingHost", "0.0.0.0", tmp, sizeof(tmp));
pingHost = inet_addr(tmp);
timeout = getInt(buf, "MentoHUST", "Timeout", D_TIMEOUT) % 100;
echoInterval = getInt(buf, "MentoHUST", "EchoInterval", D_ECHOINTERVAL) % 1000;
restartWait = getInt(buf, "MentoHUST", "RestartWait", D_RESTARTWAIT) % 100;
startMode = getInt(buf, "MentoHUST", "StartMode", D_STARTMODE) % 3;
dhcpMode = getInt(buf, "MentoHUST", "DhcpMode", D_DHCPMODE) % 4;
#ifndef NO_NOTIFY
showNotify = getInt(buf, "MentoHUST", "ShowNotify", D_SHOWNOTIFY) % 21;
#endif
*daemonMode = getInt(buf, "MentoHUST", "DaemonMode", D_DAEMONMODE) % 4;
maxFail = getInt(buf, "MentoHUST", "MaxFail", D_MAXFAIL);
free(buf);
return 0;
}
static void readArg(char argc, char **argv, int *saveFlag, int *exitFlag, int *daemonMode)
{
char *str, c;
int i;
for (i=1; i<argc; i++)
{
str = argv[i];
if (str[0]!='-' && str[0]!='/')
continue;
c = str[1];
if (c=='h' || c=='?' || strcmp(str, "--help")==0)
showHelp(argv[0]);
else if (c == 'w')
*saveFlag = 1;
else if (c == 'k') {
if (strlen(str) > 2)
*exitFlag = 2;
else {
*exitFlag = 1;
return;
}
} else if (strlen(str) > 2) {
if (c == 'u')
strncpy(userName, str+2, sizeof(userName)-1);
else if (c == 'p')
strncpy(password, str+2, sizeof(password)-1);
else if (c == 'n')
strncpy(nic, str+2, sizeof(nic)-1);
else if (c == 'f')
strncpy(dataFile, str+2, sizeof(dataFile)-1);
else if (c == 'c')
strncpy(dhcpScript, str+2, sizeof(dhcpScript)-1);
else if (c=='v' && strlen(str+2)>=3) {
unsigned ver[2];
if (sscanf(str+2, "%u.%u", ver, ver+1) != EOF) {
if (ver[0] == 0)
bufType = 0;
else {
version[0] = ver[0];
version[1] = ver[1];
bufType = 1;
}
}
}
else if (c == 'i')
ip = inet_addr(str+2);
else if (c == 'm')
mask = inet_addr(str+2);
else if (c == 'g')
gateway = inet_addr(str+2);
else if (c == 's')
dns = inet_addr(str+2);
else if (c == 'o')
pingHost = inet_addr(str+2);
else if (c == 't')
timeout = atoi(str+2) % 100;
else if (c == 'e')
echoInterval = atoi(str+2) % 1000;
else if (c == 'r')
restartWait = atoi(str+2) % 100;
else if (c == 'a')
startMode = atoi(str+2) % 3;
else if (c == 'd')
dhcpMode = atoi(str+2) % 4;
#ifndef NO_NOTIFY
else if (c == 'y')
showNotify = atoi(str+2) % 21;
#endif
else if (c == 'b')
*daemonMode = atoi(str+2) % 4;
else if (c == 'l')
maxFail = atoi(str+2);
}
}
}
static void showHelp(const char *fileName)
{
char *helpString =
"用法:\t%s [-选项][参数]\n"
"选项:\t-h 显示本帮助信息\n"
"\t-k -k(退出程序) 其他(重启程序)\n"
"\t-w 保存参数到配置文件\n"
"\t-u 用户名\n"
"\t-p 密码\n"
"\t-n 网卡名\n"
"\t-i IP[默认本机IP]\n"
"\t-m 子网掩码[默认本机掩码]\n"
"\t-g 网关[默认0.0.0.0]\n"
"\t-s DNS[默认0.0.0.0]\n"
"\t-o Ping主机[默认0.0.0.0,表示关闭该功能]\n"
"\t-t 认证超时(秒)[默认8]\n"
"\t-e 响应间隔(秒)[默认30]\n"
"\t-r 失败等待(秒)[默认15]\n"
"\t-l 允许失败次数[默认0表示无限制]\n"
"\t-a 组播地址: 0(标准) 1(锐捷) 2(赛尔) [默认0]\n"
"\t-d DHCP方式: 0(不使用) 1(二次认证) 2(认证后) 3(认证前) [默认0]\n"
"\t-b 是否后台运行: 0(否) 1(是,关闭输出) 2(是,保留输出) 3(是,输出到文件) [默认0]\n"
#ifndef NO_NOTIFY
"\t-y 是否显示通知: 0(否) 1~20(是) [默认5]\n"
#endif
"\t-v 客户端版本号[默认0.00表示兼容xrgsu]\n"
"\t-f 自定义数据文件[默认不使用]\n"
"\t-c DHCP脚本[默认dhclient]\n"
"例如:\t%s -uusername -ppassword -neth0 -i192.168.0.1 -m255.255.255.0 -g0.0.0.0 -s0.0.0.0 -o0.0.0.0 -t8 -e30 -r15 -a0 -d1 -b0 -v4.10 -fdefault.mpf -cdhclient\n"
"注意使用时请确保是以root权限运行\n\n";
printf(helpString, fileName, fileName);
exit(EXIT_SUCCESS);
}
static int getAdapter()
{
pcap_if_t *alldevs, *d;
int num = 0, avail = 0, i;
char errbuf[PCAP_ERRBUF_SIZE];
if (pcap_findalldevs(&alldevs, errbuf)==-1 || alldevs==NULL)
{
printf("!! 查找网卡失败: %s\n", errbuf);
return -1;
}
for (d=alldevs; d!=NULL; d=d->next)
{
num++;
if (!(d->flags & PCAP_IF_LOOPBACK) && strcmp(d->name, "any")!=0)
{
printf("** 网卡[%d]:\t%s\n", num, d->name);
avail++;
i = num;
}
}
if (avail == 0)
{
pcap_freealldevs(alldevs);
printf("!! 找不到网卡!\n");
return -1;
}
if (avail > 1)
{
printf("?? 请选择网卡[1-%d]: ", num);
scanf("%d", &i);
if (i < 1)
i = 1;
else if (i > num)
i = num;
}
printf("** 您选择了第[%d]块网卡。\n", i);
for (d=alldevs; i>1; d=d->next, i--);
strncpy(nic, d->name, sizeof(nic)-1);
pcap_freealldevs(alldevs);
return 0;
}
static void printConfig()
{
char *addr[] = {"标准", "锐捷", "赛尔"};
char *dhcp[] = {"不使用", "二次认证", "认证后", "认证前"};
printf("** 用户名:\t%s\n", userName);
/* printf("** 密码:\t%s\n", password); */
printf("** 网卡: \t%s\n", nic);
if (gateway)
printf("** 网关地址:\t%s\n", formatIP(gateway));
if (dns)
printf("** DNS地址:\t%s\n", formatIP(dns));
if (pingHost)
printf("** 智能重连:\t%s\n", formatIP(pingHost));
printf("** 认证超时:\t%u秒\n", timeout);
printf("** 响应间隔:\t%u秒\n", echoInterval);
printf("** 失败等待:\t%u秒\n", restartWait);
printf("** 允许失败:\t%u次\n", maxFail);
printf("** 组播地址:\t%s\n", addr[startMode]);
printf("** DHCP方式:\t%s\n", dhcp[dhcpMode]);
#ifndef NO_NOTIFY
if (showNotify)
printf("** 通知超时:\t%d秒\n", showNotify);
#endif
if (bufType >= 2)
printf("** 数据文件:\t%s\n", dataFile);
if (dhcpMode != 0)
printf("** DHCP脚本:\t%s\n", dhcpScript);
}
static int openPcap()
{
char buf[PCAP_ERRBUF_SIZE], *fmt;
struct bpf_program fcode;
if ((hPcap = pcap_open_live(nic, 2048, 1, 1000, buf)) == NULL)
{
printf("!! 打开网卡%s失败: %s\n", nic, buf);
return -1;
}
fmt = formatHex(localMAC, 6);
#ifndef NO_ARP
sprintf(buf, "((ether proto 0x888e and (ether dst %s or ether dst 01:80:c2:00:00:03)) "
"or ether proto 0x0806) and not ether src %s", fmt, fmt);
#else
sprintf(buf, "ether proto 0x888e and (ether dst %s or ether dst 01:80:c2:00:00:03) "
"and not ether src %s", fmt, fmt);
#endif
if (pcap_compile(hPcap, &fcode, buf, 0, 0xffffffff) == -1
|| pcap_setfilter(hPcap, &fcode) == -1)
{
printf("!! 设置pcap过滤器失败: %s\n", pcap_geterr(hPcap));
return -1;
}
pcap_freecode(&fcode);
return 0;
}
static void saveConfig(int daemonMode)
{
char *buf = loadFile(CFG_FILE);
if (buf == NULL) {
buf = (char *)malloc(1);
buf[0] = '\0';
}
setString(&buf, "MentoHUST", "DhcpScript", dhcpScript);
setString(&buf, "MentoHUST", "DataFile", dataFile);
if (bufType != 0) {
char ver[10];
sprintf(ver, "%u.%u", version[0], version[1]);
setString(&buf, "MentoHUST", "Version", ver);
} else
setString(&buf, "MentoHUST", "Version", "0.00");
#ifndef NO_NOTIFY
setInt(&buf, "MentoHUST", "ShowNotify", showNotify);
#endif
setInt(&buf, "MentoHUST", "DaemonMode", daemonMode);
setInt(&buf, "MentoHUST", "DhcpMode", dhcpMode);
setInt(&buf, "MentoHUST", "StartMode", startMode);
setInt(&buf, "MentoHUST", "MaxFail", maxFail);
setInt(&buf, "MentoHUST", "RestartWait", restartWait);
setInt(&buf, "MentoHUST", "EchoInterval", echoInterval);
setInt(&buf, "MentoHUST", "Timeout", timeout);
setString(&buf, "MentoHUST", "PingHost", formatIP(pingHost));
setString(&buf, "MentoHUST", "DNS", formatIP(dns));
setString(&buf, "MentoHUST", "Gateway", formatIP(gateway));
setString(&buf, "MentoHUST", "Mask", formatIP(mask));
setString(&buf, "MentoHUST", "IP", formatIP(ip));
setString(&buf, "MentoHUST", "Nic", nic);
#ifdef NO_ENCODE_PASS
setString(&buf, "MentoHUST", "Password", password);
#else
char pass[ACCOUNT_SIZE*4/3];
encodePass(pass, password);
setString(&buf, "MentoHUST", "EncodePass", pass);
#endif
setString(&buf, "MentoHUST", "Username", userName);
if (saveFile(buf, CFG_FILE) != 0)
printf("!! 保存认证参数到%s失败\n", CFG_FILE);
else
printf("** 认证参数已成功保存到%s.\n", CFG_FILE);
free(buf);
}
static void checkRunning(int exitFlag, int daemonMode)
{
struct flock fl;
lockfd = open (LOCK_FILE, O_RDWR|O_CREAT, LOCKMODE);
if (lockfd < 0) {
perror("!! 打开锁文件失败"); /* perror真的很好啊以前没用它真是太亏了 */
goto error_exit;
}
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
fl.l_type = F_WRLCK;
if (fcntl(lockfd, F_GETLK, &fl) < 0) {
perror("!! 获取文件锁失败");
goto error_exit;
}
if (exitFlag) {
if (fl.l_type != F_UNLCK) {
printf(">> 已发送退出信号给MentoHUST进程(PID=%d).\n", fl.l_pid);
if (kill(fl.l_pid, SIGINT) == -1)
perror("!! 结束进程失败");
}
else
printf("!! 没有MentoHUST正在运行\n");
if (exitFlag == 1)
exit(EXIT_SUCCESS);
}
else if (fl.l_type != F_UNLCK) {
printf("!! MentoHUST已经运行(PID=%d)!\n", fl.l_pid);
exit(EXIT_FAILURE);
}
if (daemonMode) { /* 貌似我过早进入后台模式了,就给个选项保留输出或者输出到文件吧 */
printf(">> 进入后台运行模式,使用参数-k可退出认证。\n");
if (daemon(0, (daemonMode+1)%2))
perror("!! 后台运行失败");
else if (daemonMode == 3) {
freopen(LOG_FILE, "w", stdout);
freopen(LOG_FILE, "a", stderr);
}
}
fl.l_type = F_WRLCK;
fl.l_pid = getpid();
if (fcntl(lockfd, F_SETLKW, &fl) < 0) {
perror("!! 加锁失败");
goto error_exit;
}
return;
error_exit:
#ifndef NO_NOTIFY
if (showNotify)
show_notify("MentoHUST - 错误提示", "操作锁文件失败请检查是否为root权限");
#endif
exit(EXIT_FAILURE);
}

13
mentohust/src/myconfig.h Normal file
View File

@ -0,0 +1,13 @@
/*
* Copyright (C) 2009, HustMoon Studio
*
* myconfig.h
*
* HustMoon@BYHH
*/
#ifndef HUSTMOON_MYCONFIG_H
#define HUSTMOON_MYCONFIG_H
void initConfig(int argc, char **argv); /* 初始化配置 */
#endif

522
mentohust/src/myfunc.c Normal file
View File

@ -0,0 +1,522 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* myfunc.c
*
* HustMoon@BYHH
*/
#include "myfunc.h"
#include "md5.h"
#include "mycheck.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>
#ifndef SIOCGIFHWADDR /* BSD、MacOS */
#include <net/if_dl.h>
#include <ifaddrs.h>
#endif
#include <sys/poll.h>
const u_char STANDARD_ADDR[] = {0x01,0x80,0xC2,0x00,0x00,0x03};
const u_char RUIJIE_ADDR[] = {0x01,0xD0,0xF8,0x00,0x00,0x03};
static const char *DATAFILE = "/etc/mentohust/"; /* 默认数据文件(目录) */
static int dataOffset; /* 抓包偏移 */
static u_int32_t echoKey = 0, echoNo = 0; /* Echo阶段所需 */
u_char *fillBuf = NULL; /* 填充包地址 */
int fillSize = 0; /* 填充包大小 */
int bufType = 0; /*0内置xrgsu 1内置Win 2仅文件 3文件+校验*/
u_char version[2]; /* 版本 */
#ifndef NO_ARP
u_int32_t rip = 0; /* 实际IP */
u_char gateMAC[6]; /* 网关MAC */
#endif
extern char password[];
extern char nic[];
extern char dataFile[];
extern u_int32_t ip, mask, gateway, dns, pingHost;
extern u_char localMAC[], destMAC[];
extern unsigned startMode, dhcpMode;
static int checkFile(); /* 检查数据文件 */
static int getVersion(); /* 获取8021x.exe版本号 */
static int getAddress(); /* 获取网络地址 */
static u_char encode(u_char base); /* 锐捷算法颠倒一个字节的8位 */
static void checkSum(u_char *buf); /* 锐捷算法,计算两个字节的检验值 */
static int setProperty(u_char type, const u_char *value, int length); /* 设置指定属性 */
static int readPacket(int type); /* 读取数据 */
static int Check(const u_char *md5Seed); /* 校验算法 */
char *formatIP(u_int32_t ip)
{
static char tmp[16];
u_char *p = (u_char *)(&ip);
sprintf(tmp, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
return tmp;
}
char *formatHex(const void *buf, int length)
{
static char hex[385];
u_char *p = (u_char *)buf;
int i;
if (length > 128)
length = 128;
for (i=0; i<length; i++)
sprintf(hex+3*i,"%02x:", p[i]);
hex[3*length-1] = '\0';
return hex;
}
static int checkFile() {
u_char Buf[16], *buf=Buf;
FILE *fp = NULL;
if ((fp=fopen(dataFile, "rb")) == NULL)
goto fileError;
if (fread(buf, 16, 1, fp)<1 || memcmp(buf, "HUST", 4)!=0) {
fclose(fp);
goto fileError;
}
dataOffset = (int)LTOBL(*(u_int32_t *)buf ^ *(u_int32_t *)(buf + 8)) + 16;
fseek(fp, 0, SEEK_END);
fillSize = ftell(fp);
fclose(fp);
if (dataOffset < 16)
goto fileError;
fillSize = (fillSize - dataOffset) / 2 + 0x17;
if (fillSize<0x80 || fillSize>0x397)
goto fileError;
return 0;
fileError:
if (dataFile[strlen(dataFile)-1] != '/')
printf("!! 所选文件%s无效改用内置数据认证。\n", dataFile);
return -1;
}
static int getVersion() {
char file[0x100], *p;
DWORD ver;
strcpy(file, dataFile);
if ((p=strrchr(file, '/')+1) == (void *)1)
p = file;
strcpy(p, "8021x.exe");
if ((ver=getVer(file)) == (DWORD)-1)
return -1;
p = (char *)&ver;
version[0] = p[2];
version[1] = p[0];
bufType = 1;
return 0;
}
void newBuffer()
{
if (dataFile[0] == '\0')
strcpy(dataFile, DATAFILE);
getVersion();
if (checkFile() == 0)
bufType += 2;
else fillSize = (bufType==0 ? 0x80 : 0x1d7);
fillBuf = (u_char *)malloc(fillSize);
}
static int getAddress()
{
struct ifreq ifr;
#ifndef SIOCGIFHWADDR /* BSD、MacOS */
struct ifaddrs *ifap, *p = NULL;
struct sockaddr_dl *sdl;
#endif
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
printf("!! 创建套接字失败!\n");
return -1;
}
strcpy(ifr.ifr_name, nic);
#ifdef SIOCGIFHWADDR
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
goto getMACError;
memcpy(localMAC, ifr.ifr_hwaddr.sa_data, 6);
#else
if (getifaddrs(&ifap) == 0)
{
for (p=ifap; p; p=p->ifa_next)
{
if (p->ifa_name && strcmp(p->ifa_name, nic)==0)
{
sdl = (struct sockaddr_dl *)p->ifa_addr;
memcpy(localMAC, sdl->sdl_data + sdl->sdl_nlen, 6);
break;
}
}
freeifaddrs(ifap);
}
if (p == NULL)
goto getMACError;
#endif
if (startMode == 0)
memcpy(destMAC, STANDARD_ADDR, 6);
else if (startMode == 1)
memcpy(destMAC, RUIJIE_ADDR, 6);
#ifndef NO_ARP
gateMAC[0] = 0xFE;
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
printf("!! 在网卡%s上获取IP失败!\n", nic);
else {
rip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
if (gateway!=0 && (startMode%3!=2 || ((u_char *)&gateway)[3]!=0x02))
gateMAC[0] = 0xFF;
}
if (dhcpMode!=0 || ip==-1)
ip = rip;
#else
if (dhcpMode!=0 || ip==-1) {
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
printf("!! 在网卡%s上获取IP失败!\n", nic);
else
ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
}
#endif
if (dhcpMode!=0 || mask==-1) {
if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0)
printf("!! 在网卡%s上获取子网掩码失败!\n", nic);
else
mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
}
close(sock);
printf("** 本机MAC:\t%s\n", formatHex(localMAC, 6));
printf("** 使用IP:\t%s\n", formatIP(ip));
printf("** 子网掩码:\t%s\n", formatIP(mask));
return 0;
getMACError:
close(sock);
printf("!! 在网卡%s上获取MAC失败!\n", nic);
return -1;
}
static u_char encode(u_char base) /* 算法将一个字节的8位颠倒并取反 */
{
u_char result = 0;
int i;
for (i=0; i<8; i++)
{
result <<= 1;
result |= base&0x01;
base >>= 1;
}
return ~result;
}
static void checkSum(u_char *buf) /* 算法计算两个字节的checksum */
{
u_char table[] =
{
0x00,0x00,0x21,0x10,0x42,0x20,0x63,0x30,0x84,0x40,0xA5,0x50,0xC6,0x60,0xE7,0x70,
0x08,0x81,0x29,0x91,0x4A,0xA1,0x6B,0xB1,0x8C,0xC1,0xAD,0xD1,0xCE,0xE1,0xEF,0xF1,
0x31,0x12,0x10,0x02,0x73,0x32,0x52,0x22,0xB5,0x52,0x94,0x42,0xF7,0x72,0xD6,0x62,
0x39,0x93,0x18,0x83,0x7B,0xB3,0x5A,0xA3,0xBD,0xD3,0x9C,0xC3,0xFF,0xF3,0xDE,0xE3,
0x62,0x24,0x43,0x34,0x20,0x04,0x01,0x14,0xE6,0x64,0xC7,0x74,0xA4,0x44,0x85,0x54,
0x6A,0xA5,0x4B,0xB5,0x28,0x85,0x09,0x95,0xEE,0xE5,0xCF,0xF5,0xAC,0xC5,0x8D,0xD5,
0x53,0x36,0x72,0x26,0x11,0x16,0x30,0x06,0xD7,0x76,0xF6,0x66,0x95,0x56,0xB4,0x46,
0x5B,0xB7,0x7A,0xA7,0x19,0x97,0x38,0x87,0xDF,0xF7,0xFE,0xE7,0x9D,0xD7,0xBC,0xC7,
0xC4,0x48,0xE5,0x58,0x86,0x68,0xA7,0x78,0x40,0x08,0x61,0x18,0x02,0x28,0x23,0x38,
0xCC,0xC9,0xED,0xD9,0x8E,0xE9,0xAF,0xF9,0x48,0x89,0x69,0x99,0x0A,0xA9,0x2B,0xB9,
0xF5,0x5A,0xD4,0x4A,0xB7,0x7A,0x96,0x6A,0x71,0x1A,0x50,0x0A,0x33,0x3A,0x12,0x2A,
0xFD,0xDB,0xDC,0xCB,0xBF,0xFB,0x9E,0xEB,0x79,0x9B,0x58,0x8B,0x3B,0xBB,0x1A,0xAB,
0xA6,0x6C,0x87,0x7C,0xE4,0x4C,0xC5,0x5C,0x22,0x2C,0x03,0x3C,0x60,0x0C,0x41,0x1C,
0xAE,0xED,0x8F,0xFD,0xEC,0xCD,0xCD,0xDD,0x2A,0xAD,0x0B,0xBD,0x68,0x8D,0x49,0x9D,
0x97,0x7E,0xB6,0x6E,0xD5,0x5E,0xF4,0x4E,0x13,0x3E,0x32,0x2E,0x51,0x1E,0x70,0x0E,
0x9F,0xFF,0xBE,0xEF,0xDD,0xDF,0xFC,0xCF,0x1B,0xBF,0x3A,0xAF,0x59,0x9F,0x78,0x8F,
0x88,0x91,0xA9,0x81,0xCA,0xB1,0xEB,0xA1,0x0C,0xD1,0x2D,0xC1,0x4E,0xF1,0x6F,0xE1,
0x80,0x10,0xA1,0x00,0xC2,0x30,0xE3,0x20,0x04,0x50,0x25,0x40,0x46,0x70,0x67,0x60,
0xB9,0x83,0x98,0x93,0xFB,0xA3,0xDA,0xB3,0x3D,0xC3,0x1C,0xD3,0x7F,0xE3,0x5E,0xF3,
0xB1,0x02,0x90,0x12,0xF3,0x22,0xD2,0x32,0x35,0x42,0x14,0x52,0x77,0x62,0x56,0x72,
0xEA,0xB5,0xCB,0xA5,0xA8,0x95,0x89,0x85,0x6E,0xF5,0x4F,0xE5,0x2C,0xD5,0x0D,0xC5,
0xE2,0x34,0xC3,0x24,0xA0,0x14,0x81,0x04,0x66,0x74,0x47,0x64,0x24,0x54,0x05,0x44,
0xDB,0xA7,0xFA,0xB7,0x99,0x87,0xB8,0x97,0x5F,0xE7,0x7E,0xF7,0x1D,0xC7,0x3C,0xD7,
0xD3,0x26,0xF2,0x36,0x91,0x06,0xB0,0x16,0x57,0x66,0x76,0x76,0x15,0x46,0x34,0x56,
0x4C,0xD9,0x6D,0xC9,0x0E,0xF9,0x2F,0xE9,0xC8,0x99,0xE9,0x89,0x8A,0xB9,0xAB,0xA9,
0x44,0x58,0x65,0x48,0x06,0x78,0x27,0x68,0xC0,0x18,0xE1,0x08,0x82,0x38,0xA3,0x28,
0x7D,0xCB,0x5C,0xDB,0x3F,0xEB,0x1E,0xFB,0xF9,0x8B,0xD8,0x9B,0xBB,0xAB,0x9A,0xBB,
0x75,0x4A,0x54,0x5A,0x37,0x6A,0x16,0x7A,0xF1,0x0A,0xD0,0x1A,0xB3,0x2A,0x92,0x3A,
0x2E,0xFD,0x0F,0xED,0x6C,0xDD,0x4D,0xCD,0xAA,0xBD,0x8B,0xAD,0xE8,0x9D,0xC9,0x8D,
0x26,0x7C,0x07,0x6C,0x64,0x5C,0x45,0x4C,0xA2,0x3C,0x83,0x2C,0xE0,0x1C,0xC1,0x0C,
0x1F,0xEF,0x3E,0xFF,0x5D,0xCF,0x7C,0xDF,0x9B,0xAF,0xBA,0xBF,0xD9,0x8F,0xF8,0x9F,
0x17,0x6E,0x36,0x7E,0x55,0x4E,0x74,0x5E,0x93,0x2E,0xB2,0x3E,0xD1,0x0E,0xF0,0x1E
};
u_char *checkSum = buf + 0x15;
int i, index;
for (i=0; i<0x15; i++)
{
index = checkSum[0] ^ buf[i];
checkSum[0] = checkSum[1] ^ table[index*2+1];
checkSum[1] = table[index*2];
}
for (i=0; i<0x17; i++)
buf[i] = encode(buf[i]);
}
int fillHeader()
{
if (getAddress() == -1)
return -1;
memset(fillBuf, 0, fillSize);
fillBuf[0x02] = 0x13;
fillBuf[0x03] = 0x11;
if (dhcpMode != 0)
fillBuf[0x04] = 0x01; /* DHCP位使用1、不使用0 */
memcpy(fillBuf+0x05, &ip, 4);
memcpy(fillBuf+0x09, &mask, 4);
memcpy(fillBuf+0x0D, &gateway, 4);
memcpy(fillBuf+0x11, &dns, 4);
checkSum(fillBuf);
return 0;
}
static int setProperty(u_char type, const u_char *value, int length)
{
u_char *p = fillBuf+0x46, *end = fillBuf+fillSize-length-8; /* 形如1a 28 00 00 13 11 17 22至少8个字节 */
while (p < end)
{
if (*p == 0x1a) /* 有些老版本没有前两个字节包括xrgsu */
p += 2;
if (p[4] == type)
{
memcpy(p+4+p[5]-length, value, length);
return 0;
}
p += p[5] + 4;
}
return -1;
}
static int readPacket(int type)
{
u_char dhcp[] = {0x00};
FILE *fp = fopen(dataFile, "rb");
if (fp == NULL)
goto fileError;
type %= 2; /* 偶数读Start包奇数读Md5包 */
fseek(fp, dataOffset+(fillSize-0x17)*type, SEEK_SET);
if (fread(fillBuf+0x17, fillSize-0x17, 1, fp) < 1) /* 前0x17字节是地址及校验值 */
{
fclose(fp);
goto fileError;
}
fclose(fp);
if (dhcpMode == 1) /* 二次认证第一次 */
dhcp[0] = 0x01;
setProperty(0x18, dhcp, 1);
setProperty(0x2D, localMAC, 6);
if (bufType == 3)
memcpy(fillBuf+0x3b, version, 2);
return 0;
fileError:
printf("!! 所选文件%s无效改用内置数据认证。\n", dataFile);
bufType -= 2;
if (bufType==1 && fillSize<0x1d7) {
free(fillBuf);
fillSize = 0x1d7;
fillBuf = (u_char *)malloc(fillSize);
}
return -1;
}
void fillStartPacket()
{
if (bufType <= 1) { /* 使用xrgsu */
const u_char packet0[] = {
0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2e,0x65,0x78,0x65,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x13,0x11,0x00,0x28,0x1a,
0x28,0x00,0x00,0x13,0x11,0x17,0x22,0x91,0x66,0x64,0x93,0x67,0x60,0x65,0x62,0x62,
0x94,0x61,0x69,0x67,0x63,0x91,0x93,0x92,0x68,0x66,0x93,0x91,0x66,0x95,0x65,0xaa,
0xdc,0x64,0x98,0x96,0x6a,0x9d,0x66,0x00,0x00,0x13,0x11,0x18,0x06,0x02,0x00,0x00
};
const u_char packet1[] = {
0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2e,0x65,0x78,0x65,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x04,0x0a,0x00,0x02,0x00,0x00,0x00,0x13,0x11,0x01,0x8c,0x1a,
0x28,0x00,0x00,0x13,0x11,0x17,0x22,0x36,0x38,0x44,0x43,0x31,0x32,0x33,0x42,0x37,
0x45,0x42,0x32,0x33,0x39,0x46,0x32,0x33,0x41,0x38,0x43,0x30,0x30,0x30,0x33,0x38,
0x38,0x34,0x39,0x38,0x36,0x33,0x39,0x1a,0x0c,0x00,0x00,0x13,0x11,0x18,0x06,0x00,
0x00,0x00,0x00,0x1a,0x0e,0x00,0x00,0x13,0x11,0x2d,0x08,0x00,0x00,0x00,0x00,0x00,
0x00,0x1a,0x08,0x00,0x00,0x13,0x11,0x2f,0x02,0x1a,0x09,0x00,0x00,0x13,0x11,0x35,
0x03,0x01,0x1a,0x18,0x00,0x00,0x13,0x11,0x36,0x12,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x18,0x00,0x00,0x13,0x11,
0x38,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x86,
0x13,0x4c,0x1a,0x88,0x00,0x00,0x13,0x11,0x4d,0x82,0x36,0x38,0x64,0x63,0x31,0x32,
0x33,0x62,0x30,0x37,0x65,0x62,0x32,0x33,0x39,0x66,0x32,0x33,0x61,0x38,0x30,0x64,
0x63,0x66,0x32,0x35,0x38,0x37,0x35,0x64,0x30,0x35,0x37,0x37,0x30,0x63,0x37,0x32,
0x31,0x65,0x34,0x35,0x36,0x34,0x35,0x65,0x35,0x33,0x37,0x61,0x62,0x33,0x35,0x31,
0x62,0x62,0x36,0x33,0x31,0x35,0x35,0x61,0x65,0x31,0x36,0x32,0x36,0x31,0x36,0x37,
0x65,0x62,0x30,0x39,0x32,0x32,0x33,0x65,0x32,0x61,0x30,0x61,0x37,0x38,0x30,0x33,
0x31,0x31,0x36,0x31,0x61,0x63,0x30,0x39,0x64,0x61,0x32,0x64,0x63,0x30,0x37,0x33,
0x36,0x39,0x33,0x61,0x34,0x66,0x35,0x61,0x32,0x39,0x32,0x38,0x36,0x37,0x35,0x31,
0x66,0x39,0x37,0x66,0x34,0x64,0x30,0x34,0x36,0x38,0x1a,0x28,0x00,0x00,0x13,0x11,
0x39,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1a,0x48,0x00,0x00,0x13,0x11,0x54,0x42,0x48,0x55,0x53,0x54,0x4d,0x4f,
0x4f,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x08,0x00,0x00,0x13,0x11,
0x55,0x02,0x1a,0x09,0x00,0x00,0x13,0x11,0x62,0x03,0x00,0x00,0x00,0x00,0x00,0x00
};
u_char dhcp[] = {0x00};
if (dhcpMode == 1) /* 二次认证第一次 */
dhcp[0] = 0x01;
if (bufType == 1) {
memcpy(fillBuf+0x17, packet1, sizeof(packet1));
memcpy(fillBuf+0x3b, version, 2);
} else
memcpy(fillBuf+0x17, packet0, sizeof(packet0));
setProperty(0x18, dhcp, 1);
setProperty(0x2D, localMAC, 6);
}
else if (readPacket(0) == -1) /* 读取数据失败就用默认的填充 */
fillStartPacket();
}
void fillMd5Packet(const u_char *md5Seed)
{
if (bufType <= 1) { /* 不使用数据包? */
/* xrgsu的Md5包与Start包只有一个字节的差异若以其他版本为基础可进一步区别对待 */
fillStartPacket();
if (bufType == 1)
Check(md5Seed);
} else {
if (readPacket(1) == -1)
fillMd5Packet(md5Seed);
else
Check(md5Seed);
}
echoNo = 0x0000102B; /* 初始化echoNo */
}
static int Check(const u_char *md5Seed) /* 客户端校验 */
{
char final_str[129];
int value;
printf("** 客户端版本:\t%d.%d\n", fillBuf[0x3B], fillBuf[0x3C]);
printf("** MD5种子:\t%s\n", formatHex(md5Seed, 16));
value = check_init(dataFile);
if (value == -1) {
printf("!! 缺少8021x.exe信息客户端校验无法继续\n");
return 1;
}
V2_check(md5Seed, final_str);
printf("** V2校验值:\t%s\n", final_str);
setProperty(0x17, (u_char *)final_str, 32);
check_free();
return 0;
}
void fillEchoPacket(u_char *echoBuf)
{
int i;
u_int32_t dd1=htonl(echoKey + echoNo), dd2=htonl(echoNo);
u_char *bt1=(u_char *)&dd1, *bt2=(u_char *)&dd2;
echoNo++;
for (i=0; i<4; i++)
{
echoBuf[0x18+i] = encode(bt1[i]);
echoBuf[0x22+i] = encode(bt2[i]);
}
}
void getEchoKey(const u_char *capBuf)
{
int i, offset = 0x1c+capBuf[0x1b]+0x69+24; /* 通过比较了大量抓包,通用的提取点就是这样的 */
u_char *base;
echoKey = ntohl(*(u_int32_t *)(capBuf+offset));
base = (u_char *)(&echoKey);
for (i=0; i<4; i++)
base[i] = encode(base[i]);
}
u_char *checkPass(u_char id, const u_char *md5Seed, int seedLen)
{
u_char md5Src[80];
int md5Len = strlen(password);
md5Src[0] = id;
memcpy(md5Src+1, password, md5Len);
md5Len++;
if (startMode % 3 == 2) /* 赛尔? */
{
memcpy(md5Src+md5Len, "xxghlmxhzb", 10);
md5Len += 10;
}
memcpy(md5Src+md5Len, md5Seed, seedLen);
md5Len += seedLen;
return ComputeHash(md5Src, md5Len);
}
void fillCernetAddr(u_char *buf)
{
memcpy(buf+0x18, &ip, 4);
memcpy(buf+0x1C, &mask, 4);
memcpy(buf+0x20, &gateway, 4);
memset(buf+0x24, 0, 4); /* memcpy(buf+0x24, &dns, 4); */
}
int isOnline()
{
u_char echoPacket[] =
{
0x08,0x00,0x61,0xb2,0x02,0x00,0x01,0x00,0x57,0x65,0x6C,0x63,0x6F,0x6D,0x65,0x20,
0x74,0x6F,0x20,0x4D,0x65,0x6E,0x74,0x6F,0x48,0x55,0x53,0x54,0x21,0x0A,0x43,0x6F,
0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x39,
0x20,0x48,0x75,0x73,0x74,0x4D,0x6F,0x6F,0x6E,0x20,0x53,0x74,0x75,0x64,0x69,0x6F
};
int sock=-1, rtVal, t;
struct pollfd pfd;
struct sockaddr_in dest;
if (pingHost == 0)
return 0;
memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = pingHost;
if ((sock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
goto pingError;
pfd.fd = sock;
pfd.events = POLLIN;
for (t=1; t<=3; t++) {
if (sendto(sock, echoPacket, sizeof(echoPacket), 0,
(struct sockaddr *)&dest, sizeof(dest)) < 0)
goto pingError;
rtVal = poll(&pfd, 1, t*1000);
if (rtVal == -1)
goto pingError;
if (rtVal > 0) {
close(sock);
return 0;
}
}
close(sock);
return -1;
pingError:
perror("!! Ping主机出错关闭该功能");
if (sock != -1)
close(sock);
pingHost = 0;
return 0;
}

26
mentohust/src/myfunc.h Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright (C) 2009, HustMoon Studio
*
* myfunc.h
*
* HustMoon@BYHH
*/
#ifndef HUSTMOON_MYFUNC_H
#define HUSTMOON_MYFUNC_H
#include <sys/types.h>
char *formatIP(u_int32_t ip); /* 格式化IP */
char *formatHex(const void *buf, int length); /* 格式化成十六进制形式 */
void newBuffer(); /* 检测数据文件有效性并分配内存 */
int fillHeader(); /* 填充网络地址及校验值部分 */
void fillStartPacket(); /* 填充Start包 */
void fillMd5Packet(const u_char *md5Seed); /* 填充Md5包 */
void fillEchoPacket(u_char *buf); /* 填充Echo包 */
void getEchoKey(const u_char *capBuf); /* 获取EchoKey */
u_char *checkPass(u_char id, const u_char *md5Seed, int seedLen); /* 计算密码的md5 */
void fillCernetAddr(u_char *buf); /* 填充赛尔网络地址 */
int isOnline(); /* ping主机判断是否掉线 */
#endif

203
mentohust/src/myini.c Normal file
View File

@ -0,0 +1,203 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* myini.c
* ini文件+ini文件
* HustMoon@BYHH
* 2009.10.8
*/
#include "myini.h"
#include <stdio.h>
#include <string.h>
#define NOT_COMMENT(c) (c!=';' && c!='#') /* 不是注释行 */
#ifndef strnicmp
#define strnicmp strncasecmp
#endif
static void getLine(const char *buf, int inStart, int *lineStart, int *lineEnd);
static int findKey(const char *buf, const char *section, const char *key,
int *sectionStart, int *valueStart, unsigned long *valueSize);
static int getSection(const char *buf, int inStart);
char *loadFile(const char *fileName)
{
FILE *fp = NULL;
long size = 0;
char *buf = NULL;
if ((fp=fopen(fileName, "rb")) == NULL)
return NULL;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
rewind(fp);
buf = (char *)malloc(size+1);
buf[size] = '\0';
if (fread(buf, size, 1, fp) < 1)
{
free(buf);
buf = NULL;
}
fclose(fp);
return buf;
}
static void getLine(const char *buf, int inStart, int *lineStart, int *lineEnd)
{
int start, end;
for (start=inStart; buf[start]==' ' || buf[start]=='\t' || buf[start]=='\r' || buf[start]=='\n'; start++);
for (end=start; buf[end]!='\r' && buf[end]!='\n' && buf[end]!='\0'; end++);
*lineStart = start;
*lineEnd = end;
}
static int findKey(const char *buf, const char *section, const char *key,
int *sectionStart, int *valueStart, unsigned long *valueSize)
{
int lineStart, lineEnd, i;
for (*sectionStart=-1, lineEnd=0; buf[lineEnd]!='\0'; )
{
getLine(buf, lineEnd, &lineStart, &lineEnd);
if (buf[lineStart] == '[')
{
for (i=++lineStart; i<lineEnd && buf[i]!=']'; i++);
if (i<lineEnd && strnicmp(buf+lineStart, section, i-lineStart)==0) /* 找到Section */
{
*sectionStart = lineStart-1;
if (key == NULL)
return -1;
}
else if (*sectionStart != -1) /* 找到Section但未找到Key */
return -1;
}
else if (*sectionStart!=-1 && NOT_COMMENT(buf[lineStart])) /* 找到Section且该行不是注释 */
{
for (i=lineStart+1; i<lineEnd && buf[i]!='='; i++);
if (i<lineEnd && strnicmp(buf+lineStart, key, i-lineStart)==0) /* 找到Key */
{
*valueStart = i + 1;
*valueSize = lineEnd - *valueStart;
return 0;
}
}
}
return -1;
}
int getString(const char *buf, const char *section, const char *key,
const char *defaultValue, char *value, unsigned long size)
{
int sectionStart, valueStart;
unsigned long valueSize;
if (findKey(buf, section, key, &sectionStart, &valueStart, &valueSize)!=0 || valueSize==0) /* 未找到? */
{
strncpy(value, defaultValue, size);
return -1;
}
if (size-1 < valueSize) /* 找到但太长? */
valueSize = size - 1;
memset(value, 0, size);
strncpy(value, buf+valueStart, valueSize);
return 0;
}
int getInt(const char *buf, const char *section, const char *key, int defaultValue)
{
char value[21] = {0};
getString(buf, section, key, "", value, sizeof(value));
if (value[0] == '\0') /* 找不到或找到但为空? */
return defaultValue;
return atoi(value);
}
void setString(char **buf, const char *section, const char *key, const char *value)
{
int sectionStart, valueStart;
unsigned long valueSize;
char *newBuf = NULL;
if (findKey(*buf, section, key, &sectionStart, &valueStart, &valueSize) == 0) /* 找到key */
{
if (value == NULL) /* 删除key? */
memmove(*buf+valueStart-strlen(key)-1, *buf+valueStart+valueSize,
strlen(*buf)+1-valueStart-valueSize);
else /* 修改key */
{
newBuf = (char *)malloc(strlen(*buf)-valueSize+strlen(value)+1);
memcpy(newBuf, *buf, valueStart);
strcpy(newBuf+valueStart, value);
strcpy(newBuf+valueStart+strlen(value), *buf+valueStart+valueSize);
free(*buf);
*buf = newBuf;
}
}
else if (sectionStart != -1) /* 找到section找不到key */
{
if (key == NULL) /* 删除section? */
{
valueStart = getSection(*buf, sectionStart+3);
if (valueStart <= sectionStart) /* 后面没有section */
(*buf)[sectionStart] = '\0';
else
memmove(*buf+sectionStart, *buf+valueStart, strlen(*buf)+1-valueStart);
}
else if (value != NULL) /* 不是要删除key */
{
newBuf = (char *)malloc(strlen(*buf)+strlen(key)+strlen(value)+4);
valueSize = sectionStart+strlen(section)+2;
memcpy(newBuf, *buf, valueSize);
sprintf(newBuf+valueSize, "\n%s=%s", key, value);
strcpy(newBuf+strlen(newBuf), *buf+valueSize);
free(*buf);
*buf = newBuf;
}
}
else /* 找不到section? */
{
if (key!=NULL && value!=NULL)
{
newBuf = (char *)malloc(strlen(*buf)+strlen(section)+strlen(key)+strlen(value)+8);
strcpy(newBuf, *buf);
sprintf(newBuf+strlen(newBuf), "\n[%s]\n%s=%s", section, key, value);
free(*buf);
*buf = newBuf;
}
}
}
static int getSection(const char *buf, int inStart)
{
int lineStart, lineEnd, i;
for (lineEnd=inStart; buf[lineEnd]!='\0'; )
{
getLine(buf, lineEnd, &lineStart, &lineEnd);
if (buf[lineStart] == '[')
{
for (i=lineStart+1; i<lineEnd && buf[i]!=']'; i++);
if (i < lineEnd)
return lineStart;
}
}
return -1;
}
void setInt(char **buf, const char *section, const char *key, int value)
{
char svalue[21];
sprintf(svalue, "%d", value);
setString(buf, section, key, svalue);
}
int saveFile(const char *buf, const char *fileName)
{
FILE *fp;
int result;
if ((fp=fopen(fileName, "wb")) == NULL)
return -1;
result = fwrite(buf, strlen(buf), 1, fp)<1 ? -1 : 0;
fclose(fp);
return result;
}

32
mentohust/src/myini.h Normal file
View File

@ -0,0 +1,32 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* myini.h
* ini文件+ini文件
* HustMoon@BYHH
* 2009.10.8
*/
#ifndef HUSTMOON_MYINI_H
#define HUSTMOON_MYINI_H
#include <stdlib.h> /* for free() */
#ifdef __cplusplus
extern "C"
{
#endif
char *loadFile(const char *fileName); /* 读取文件 */
int getString(const char *buf, const char *section, const char *key,
const char *defaultValue, char *value, unsigned long size); /* 读取字符串 */
int getInt(const char *buf, const char *section, const char *key, int defaultValue); /* 读取整数 */
void setString(char **buf, const char *section, const char *key, const char *value); /* 设置字符串value=NULL则删除keykey=NULL则删除section */
void setInt(char **buf, const char *section, const char *key, int value); /* 设置整数 */
int saveFile(const char *buf, const char *fileName); /* 写入文件 */
#ifdef __cplusplus
};
#endif
#endif

331
mentohust/src/mystate.c Normal file
View File

@ -0,0 +1,331 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* Copyright (C) 2009, HustMoon Studio
*
* mystate.c
*
* HustMoon@BYHH
* www.ehust@gmail.com
*/
#include "mystate.h"
#include "myfunc.h"
#include "dlfunc.h"
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#define MAX_SEND_COUNT 3 /* 最大超时次数 */
volatile int state = ID_DISCONNECT; /* 认证状态 */
const u_char *capBuf = NULL; /* 抓到的包 */
static u_char sendPacket[0x3E8]; /* 用来发送的包 */
static int sendCount = 0; /* 同一阶段发包计数 */
extern const u_char STANDARD_ADDR[];
extern char userName[];
extern unsigned startMode;
extern unsigned dhcpMode;
extern u_char localMAC[], destMAC[];
extern unsigned timeout;
extern unsigned echoInterval;
extern unsigned restartWait;
extern char dhcpScript[];
extern pcap_t *hPcap;
extern u_char *fillBuf;
extern unsigned fillSize;
extern u_int32_t pingHost;
#ifndef NO_ARP
extern u_int32_t rip, gateway;
extern u_char gateMAC[];
static void sendArpPacket(); /* ARP监视 */
#endif
static void setTimer(unsigned interval); /* 设置定时器 */
static int renewIP(); /* 更新IP */
static void fillEtherAddr(u_int32_t protocol); /* 填充MAC地址和协议 */
static int sendStartPacket(); /* 发送Start包 */
static int sendIdentityPacket(); /* 发送Identity包 */
static int sendChallengePacket(); /* 发送Md5 Challenge包 */
static int sendEchoPacket(); /* 发送心跳包 */
static int sendLogoffPacket(); /* 发送退出包 */
static int waitEchoPacket(); /* 等候响应包 */
static void setTimer(unsigned interval) /* 设置定时器 */
{
struct itimerval timer;
timer.it_value.tv_sec = interval;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = interval;
timer.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &timer, NULL);
}
int switchState(int type)
{
if (state == type) /* 跟上次是同一状态? */
sendCount++;
else
{
state = type;
sendCount = 0;
}
if (sendCount>=MAX_SEND_COUNT && type!=ID_ECHO) /* 超时太多次? */
{
switch (type)
{
case ID_START:
printf(">> 找不到服务器,重启认证!\n");
break;
case ID_IDENTITY:
printf(">> 发送用户名超时,重启认证!\n");
break;
case ID_CHALLENGE:
printf(">> 发送密码超时,重启认证!\n");
break;
case ID_WAITECHO:
printf(">> 等候响应包超时,自行响应!\n");
return switchState(ID_ECHO);
}
return restart();
}
switch (type)
{
case ID_DHCP:
return renewIP();
case ID_START:
return sendStartPacket();
case ID_IDENTITY:
return sendIdentityPacket();
case ID_CHALLENGE:
return sendChallengePacket();
case ID_WAITECHO: /* 塞尔的就不ping了不好计时 */
return waitEchoPacket();
case ID_ECHO:
if (pingHost && sendCount*echoInterval > 60) { /* 1分钟左右 */
if (isOnline() == -1) {
printf(">> 认证掉线,开始重连!\n");
return switchState(ID_START);
}
sendCount = 1;
}
#ifndef NO_ARP
if (gateMAC[0] != 0xFE)
sendArpPacket();
#endif
return sendEchoPacket();
case ID_DISCONNECT:
return sendLogoffPacket();
}
return 0;
}
int restart()
{
if (startMode >= 3) /* 标记服务器地址为未获取 */
startMode -= 3;
state = ID_START;
sendCount = -1;
setTimer(restartWait); /* restartWait秒后或者服务器请求后重启认证 */
return 0;
}
static int renewIP()
{
setTimer(0); /* 取消定时器 */
printf(">> 正在获取IP...\n");
system(dhcpScript);
printf(">> 操作结束。\n");
dhcpMode += 3; /* 标记为已获取123变为4565不需再认证*/
if (fillHeader() == -1)
exit(EXIT_FAILURE);
if (dhcpMode == 5)
return switchState(ID_ECHO);
return switchState(ID_START);
}
static void fillEtherAddr(u_int32_t protocol)
{
memset(sendPacket, 0, 0x3E8);
memcpy(sendPacket, destMAC, 6);
memcpy(sendPacket+0x06, localMAC, 6);
*(u_int32_t *)(sendPacket+0x0C) = htonl(protocol);
}
static int sendStartPacket()
{
if (startMode%3 == 2) /* 赛尔 */
{
if (sendCount == 0)
{
printf(">> 寻找服务器...\n");
memcpy(sendPacket, STANDARD_ADDR, 6);
memcpy(sendPacket+0x06, localMAC, 6);
*(u_int32_t *)(sendPacket+0x0C) = htonl(0x888E0101);
*(u_int16_t *)(sendPacket+0x10) = 0;
memset(sendPacket+0x12, 0xa5, 42);
setTimer(timeout);
}
return pcap_sendpacket(hPcap, sendPacket, 60);
}
if (sendCount == 0)
{
printf(">> 寻找服务器...\n");
fillStartPacket();
fillEtherAddr(0x888E0101);
memcpy(sendPacket+0x12, fillBuf, fillSize);
setTimer(timeout);
}
return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
}
static int sendIdentityPacket()
{
int nameLen = strlen(userName);
if (startMode%3 == 2) /* 赛尔 */
{
if (sendCount == 0)
{
printf(">> 发送用户名...\n");
*(u_int16_t *)(sendPacket+0x0E) = htons(0x0100);
*(u_int16_t *)(sendPacket+0x10) = *(u_int16_t *)(sendPacket+0x14) = htons(nameLen+30);
sendPacket[0x12] = 0x02;
sendPacket[0x16] = 0x01;
sendPacket[0x17] = 0x01;
fillCernetAddr(sendPacket);
memcpy(sendPacket+0x28, "03.02.05", 8);
memcpy(sendPacket+0x30, userName, nameLen);
setTimer(timeout);
}
sendPacket[0x13] = capBuf[0x13];
return pcap_sendpacket(hPcap, sendPacket, nameLen+48);
}
if (sendCount == 0)
{
printf(">> 发送用户名...\n");
fillEtherAddr(0x888E0100);
nameLen = strlen(userName);
*(u_int16_t *)(sendPacket+0x14) = *(u_int16_t *)(sendPacket+0x10) = htons(nameLen+5);
sendPacket[0x12] = 0x02;
sendPacket[0x13] = capBuf[0x13];
sendPacket[0x16] = 0x01;
memcpy(sendPacket+0x17, userName, nameLen);
memcpy(sendPacket+0x17+nameLen, fillBuf, fillSize);
setTimer(timeout);
}
return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
}
static int sendChallengePacket()
{
int nameLen = strlen(userName);
if (startMode%3 == 2) /* 赛尔 */
{
if (sendCount == 0)
{
printf(">> 发送密码...\n");
*(u_int16_t *)(sendPacket+0x0E) = htons(0x0100);
*(u_int16_t *)(sendPacket+0x10) = *(u_int16_t *)(sendPacket+0x14) = htons(nameLen+22);
sendPacket[0x12] = 0x02;
sendPacket[0x13] = capBuf[0x13];
sendPacket[0x16] = 0x04;
sendPacket[0x17] = 16;
memcpy(sendPacket+0x18, checkPass(capBuf[0x13], capBuf+0x18, capBuf[0x17]), 16);
memcpy(sendPacket+0x28, userName, nameLen);
setTimer(timeout);
}
return pcap_sendpacket(hPcap, sendPacket, nameLen+40);
}
if (sendCount == 0)
{
printf(">> 发送密码...\n");
fillMd5Packet(capBuf+0x18);
fillEtherAddr(0x888E0100);
*(u_int16_t *)(sendPacket+0x14) = *(u_int16_t *)(sendPacket+0x10) = htons(nameLen+22);
sendPacket[0x12] = 0x02;
sendPacket[0x13] = capBuf[0x13];
sendPacket[0x16] = 0x04;
sendPacket[0x17] = 16;
memcpy(sendPacket+0x18, checkPass(capBuf[0x13], capBuf+0x18, capBuf[0x17]), 16);
memcpy(sendPacket+0x28, userName, nameLen);
memcpy(sendPacket+0x28+nameLen, fillBuf, fillSize);
setTimer(timeout);
}
return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
}
static int sendEchoPacket()
{
if (startMode%3 == 2) /* 赛尔 */
{
*(u_int16_t *)(sendPacket+0x0E) = htons(0x0106);
*(u_int16_t *)(sendPacket+0x10) = 0;
memset(sendPacket+0x12, 0xa5, 42);
switchState(ID_WAITECHO); /* 继续等待 */
return pcap_sendpacket(hPcap, sendPacket, 60);
}
if (sendCount == 0)
{
u_char echo[] =
{
0x00,0x1E,0xFF,0xFF,0x37,0x77,0x7F,0x9F,0xFF,0xFF,0xD9,0x13,0xFF,0xFF,0x37,0x77,
0x7F,0x9F,0xFF,0xFF,0xF7,0x2B,0xFF,0xFF,0x37,0x77,0x7F,0x3F,0xFF
};
printf(">> 发送心跳包以保持在线...\n");
fillEtherAddr(0x888E01BF);
memcpy(sendPacket+0x10, echo, sizeof(echo));
setTimer(echoInterval);
}
fillEchoPacket(sendPacket);
return pcap_sendpacket(hPcap, sendPacket, 0x2D);
}
static int sendLogoffPacket()
{
setTimer(0); /* 取消定时器 */
if (startMode%3 == 2) /* 赛尔 */
{
*(u_int16_t *)(sendPacket+0x0E) = htons(0x0102);
*(u_int16_t *)(sendPacket+0x10) = 0;
memset(sendPacket+0x12, 0xa5, 42);
return pcap_sendpacket(hPcap, sendPacket, 60);
}
fillStartPacket(); /* 锐捷的退出包与Start包类似不过其实不这样也是没问题的 */
fillEtherAddr(0x888E0102);
memcpy(sendPacket+0x12, fillBuf, fillSize);
return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
}
static int waitEchoPacket()
{
if (sendCount == 0)
setTimer(echoInterval);
return 0;
}
#ifndef NO_ARP
static void sendArpPacket()
{
u_char arpPacket[0x3C] = {
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x06,0x00,0x01,
0x08,0x00,0x06,0x04,0x00};
if (gateMAC[0] != 0xFF) {
memcpy(arpPacket, gateMAC, 6);
memcpy(arpPacket+0x06, localMAC, 6);
arpPacket[0x15]=0x02;
memcpy(arpPacket+0x16, localMAC, 6);
memcpy(arpPacket+0x1c, &rip, 4);
memcpy(arpPacket+0x20, gateMAC, 6);
memcpy(arpPacket+0x26, &gateway, 4);
pcap_sendpacket(hPcap, arpPacket, 0x3C);
}
memset(arpPacket, 0xFF, 6);
memcpy(arpPacket+0x06, localMAC, 6);
arpPacket[0x15]=0x01;
memcpy(arpPacket+0x16, localMAC, 6);
memcpy(arpPacket+0x1c, &rip, 4);
memset(arpPacket+0x20, 0, 6);
memcpy(arpPacket+0x26, &gateway, 4);
pcap_sendpacket(hPcap, arpPacket, 0x2A);
}
#endif

22
mentohust/src/mystate.h Normal file
View File

@ -0,0 +1,22 @@
/*
* Copyright (C) 2009, HustMoon Studio
*
* mystate.h
*
* HustMoon@BYHH
*/
#ifndef HUSTMOON_MYSTATE_H
#define HUSTMOON_MYSTATE_H
#define ID_DISCONNECT 0 /* 断开状态 */
#define ID_START 1 /* 寻找服务器 */
#define ID_IDENTITY 2 /* 发送用户名 */
#define ID_CHALLENGE 3 /* 发送密码 */
#define ID_ECHO 4 /* 发送心跳包 */
#define ID_DHCP 5 /* 更新IP */
#define ID_WAITECHO 6 /* 等待心跳包 */
int switchState(int type); /* 改变状态 */
int restart(); /* 重启认证 */
#endif

16708
mentohust/src/strnormalize.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
/**
* Copyright(c) 2012-2013, All Rights Reserved.
*
* @file strnormalize.h
* @details Check GBK character you could do
* code >= 0x8000 && _pGbk2Utf16[code - 0x8000] != 0
* @author cnangel
* @version 1.0.0
* @date 2012/10/09 11:44:58
*/
#ifndef __STRNORMALIZE_H__
#define __STRNORMALIZE_H__
#ifdef __cplusplus
extern "C" {
#endif
#define SNO_TO_LOWER 1
#define SNO_TO_UPPER 2
#define SNO_TO_HALF 4
#define SNO_TO_SIMPLIFIED 8
void str_normalize_init();
void str_normalize_gbk(char *text, unsigned options);
void str_normalize_utf8(char *text, unsigned options);
int gbk_to_utf8(const char *from, unsigned int from_len, char **to, unsigned int *to_len);
int utf8_to_gbk(const char *from, unsigned int from_len, char **to, unsigned int *to_len);
#ifdef __cplusplus
}
#endif
#endif /* __STRNORMALIZE_H__ */

10
mentohust/src/types.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char *POINTER;
typedef unsigned char BYTE;
typedef unsigned char UCHAR;
typedef unsigned short int WORD;
typedef int LONG;
typedef unsigned int DWORD;
typedef unsigned int UINT4;
#endif