Lua 암호화 및 도구

여기서 직접 추출한 것은cocos2dx의xxtea가 만든 것이다. 다음은 대략적인 사용이다. 만약에 자신이 이상적이지 않다고 생각한다면cocos2dx 코드에서cocos/scripting/lua-bindings/manual/CCLual Stack을 참고하면 된다.cpp의 luaLoadBuffer 이 함수에 사용법이 있어요.

// cpp      
//    cocos2dx      xxtea h,cpp  
//======================================================

#ifndef XXTEA_H
#define XXTEA_H

#include  /* for size_t & NULL declarations */

#if defined(_MSC_VER)

typedef unsigned __int32 xxtea_long;

#else

#if defined(__FreeBSD__) && __FreeBSD__ < 5
/* FreeBSD 4 doesn't have stdint.h file */
#include 
#else
#include 
#endif

typedef uint32_t xxtea_long;

#endif /* end of if defined(_MSC_VER) */

#define XXTEA_MX (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z)
#define XXTEA_DELTA 0x9e3779b9

unsigned char *xxtea_encrypt(unsigned char *data, xxtea_long data_len, unsigned char *key, xxtea_long key_len, xxtea_long *ret_length);
unsigned char *xxtea_decrypt(unsigned char *data, xxtea_long data_len, unsigned char *key, xxtea_long key_len, xxtea_long *ret_length);

#endif

#include 
#include 

static void xxtea_long_encrypt(xxtea_long *v, xxtea_long len, xxtea_long *k)
{
	xxtea_long n = len - 1;
	xxtea_long z = v[n], y = v[0], p, q = 6 + 52 / (n + 1), sum = 0, e;
	if (n < 1) {
		return;
	}
	while (0 < q--) {
		sum += XXTEA_DELTA;
		e = sum >> 2 & 3;
		for (p = 0; p < n; p++) {
			y = v[p + 1];
			z = v[p] += XXTEA_MX;
		}
		y = v[0];
		z = v[n] += XXTEA_MX;
	}
}

static void xxtea_long_decrypt(xxtea_long *v, xxtea_long len, xxtea_long *k)
{
	xxtea_long n = len - 1;
	xxtea_long z = v[n], y = v[0], p, q = 6 + 52 / (n + 1), sum = q * XXTEA_DELTA, e;
	if (n < 1) {
		return;
	}
	while (sum != 0) {
		e = sum >> 2 & 3;
		for (p = n; p > 0; p--) {
			z = v[p - 1];
			y = v[p] -= XXTEA_MX;
		}
		z = v[n];
		y = v[0] -= XXTEA_MX;
		sum -= XXTEA_DELTA;
	}
}

static unsigned char *fix_key_length(unsigned char *key, xxtea_long key_len)
{
	unsigned char *tmp = (unsigned char *)malloc(16);
	memcpy(tmp, key, key_len);
	memset(tmp + key_len, '\0', 16 - key_len);
	return tmp;
}

static xxtea_long *xxtea_to_long_array(unsigned char *data, xxtea_long len, int include_length, xxtea_long *ret_len) {
	xxtea_long i, n, *result;

	n = len >> 2;
	n = (((len & 3) == 0) ? n : n + 1);
	if (include_length) {
		result = (xxtea_long *)malloc((n + 1) << 2);
		result[n] = len;
		*ret_len = n + 1;
	}
	else {
		result = (xxtea_long *)malloc(n << 2);
		*ret_len = n;
	}
	memset(result, 0, n << 2);
	for (i = 0; i < len; i++) {
		result[i >> 2] |= (xxtea_long)data[i] << ((i & 3) << 3);
	}

	return result;
}

static unsigned char *xxtea_to_byte_array(xxtea_long *data, xxtea_long len, int include_length, xxtea_long *ret_len) {
	xxtea_long i, n, m;
	unsigned char *result;

	n = len << 2;
	if (include_length) {
		m = data[len - 1];
		if ((m < n - 7) || (m > n - 4)) return NULL;
		n = m;
	}
	result = (unsigned char *)malloc(n + 1);
	for (i = 0; i < n; i++) {
		result[i] = (unsigned char)((data[i >> 2] >> ((i & 3) << 3)) & 0xff);
	}
	result[n] = '\0';
	*ret_len = n;

	return result;
}

static unsigned char *do_xxtea_encrypt(unsigned char *data, xxtea_long len, unsigned char *key, xxtea_long *ret_len) {
	unsigned char *result;
	xxtea_long *v, *k, v_len, k_len;

	v = xxtea_to_long_array(data, len, 1, &v_len);
	k = xxtea_to_long_array(key, 16, 0, &k_len);
	xxtea_long_encrypt(v, v_len, k);
	result = xxtea_to_byte_array(v, v_len, 0, ret_len);
	free(v);
	free(k);

	return result;
}

static unsigned char *do_xxtea_decrypt(unsigned char *data, xxtea_long len, unsigned char *key, xxtea_long *ret_len) {
	unsigned char *result;
	xxtea_long *v, *k, v_len, k_len;

	v = xxtea_to_long_array(data, len, 0, &v_len);
	k = xxtea_to_long_array(key, 16, 0, &k_len);
	xxtea_long_decrypt(v, v_len, k);
	result = xxtea_to_byte_array(v, v_len, 1, ret_len);
	free(v);
	free(k);

	return result;
}

unsigned char *xxtea_encrypt(unsigned char *data, xxtea_long data_len, unsigned char *key, xxtea_long key_len, xxtea_long *ret_length)
{
	unsigned char *result;

	*ret_length = 0;

	if (key_len < 16) {
		unsigned char *key2 = fix_key_length(key, key_len);
		result = do_xxtea_encrypt(data, data_len, key2, ret_length);
		free(key2);
	}
	else
	{
		result = do_xxtea_encrypt(data, data_len, key, ret_length);
	}

	return result;
}

unsigned char *xxtea_decrypt(unsigned char *data, xxtea_long data_len, unsigned char *key, xxtea_long key_len, xxtea_long *ret_length)
{
	unsigned char *result;

	*ret_length = 0;

	if (key_len < 16) {
		unsigned char *key2 = fix_key_length(key, key_len);
		result = do_xxtea_decrypt(data, data_len, key2, ret_length);
		free(key2);
	}
	else
	{
		result = do_xxtea_decrypt(data, data_len, key, ret_length);
	}

	return result;
}

void skipBOM(const char*& chunk, int& chunkSize)
{
	// UTF-8 BOM? skip
	if (static_cast(chunk[0]) == 0xEF &&
		static_cast(chunk[1]) == 0xBB &&
		static_cast(chunk[2]) == 0xBF)
	{
		chunk += 3;
		chunkSize -= 3;
	}
}

//======================================================




로드 함수에 추가
	char _xxteaSign[] = "xxtea";
	int _xxteaSignLen = sizeof(_xxteaSign) - 1;
	char _xxteaKey[] = "xxxxxx";
	int _xxteaKeyLen = sizeof(_xxteaKey) - 1;

	char *chunk = data_;
	int chunkSize = size_;
	
	// decrypt XXTEA
	if (strncmp(chunk, _xxteaSign, _xxteaSignLen) == 0)
	{
		xxtea_long len = 0;
		unsigned char* result = xxtea_decrypt((unsigned char*)chunk + _xxteaSignLen,
			(xxtea_long)chunkSize - _xxteaSignLen,
			(unsigned char*)_xxteaKey,
			(xxtea_long)_xxteaKeyLen,
			&len);

		skipBOM((const char*&)result, (int&)len);

		if (luaL_loadbuffer(luaState, (char*)result, len, filename))
		{
			free(result);
			const char* message = lua_tostring(luaState, -1);
			printf("Load decode Buffer failed for %s: %s", filename, message);
			lua_pop(luaState, 1);
			return false;
		}
		else
		{
			free(result);
		}
}
else
{
		if (luaL_loadbuffer(luaState, data_, size_, filename))
		{
			const char* message = lua_tostring(luaState, -1);
			printf("Load Buffer failed for %s: %s", filename, message);
			lua_pop(luaState, 1);
			return false;
		}

}


대개 이런 코드인데, 여기는 구체적인 상황을 보고 약간의 조정을 진행해야 한다
암호화 도구는 Golang이 작성한 것으로 주로 편리합니다. 이것은 명령행의 형식으로 진행되어 일괄 처리로 사용하기 편리합니다.
package main

///                    ,  lua      

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/xxtea/xxtea-go/xxtea"
)

//                  ,        。
func WalkDir(dirPth, suffix string) (files []string, err error) {
	files = make([]string, 0, 30)
	suffix = strings.ToUpper(suffix)                                                     //          
	err = filepath.Walk(dirPth, func(filename string, fi os.FileInfo, err error) error { //    
		//if err != nil { //    
		// return err
		//}
		if fi.IsDir() { //     
			return nil
		}
		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
			files = append(files, filename)
		}
		return nil
	})
	return files, err
}

func CodecLua(indir string, outdir string, sign string, key string) {
	inlen := len(indir)
	//	outlen := len(outdir)
	keybytes := []byte(key)
	signbytes := []byte(sign)

	files, err := WalkDir(indir, "lua")
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, v := range files {

		newfilepath := outdir + v[inlen:]
		newfilepath = strings.Replace(newfilepath, "\\", "/", 100)

		rs, er := ioutil.ReadFile(v)
		if er == nil {
			outbytes := xxtea.Encrypt(rs, keybytes)

			newpath := newfilepath
			index := strings.LastIndex(newfilepath, "/")
			if index > -1 {
				newpath = newfilepath[:index]
			}

			//			fmt.Println(k, newpath, v, newpath)
			os.MkdirAll(newpath, os.ModePerm)

			buffer := bytes.NewBuffer(signbytes)
			buffer.Write(outbytes)

			ioutil.WriteFile(newfilepath, buffer.Bytes(), os.ModePerm)
			//		ioutil.WriteFile(newfilepath, outbytes, os.ModeAppend)
		} else {
			fmt.Println("error cant read file:", v)
		}

	}
}

func main() {
	if len(os.Args) < 4 {
		fmt.Println("less of paramer")
		return
	}

	indir := os.Args[1]
	outdir := os.Args[2]
	sign := os.Args[3]
	key := os.Args[4]
	fmt.Println("============>>> codec lua =======>")
	fmt.Println("indir:", indir)
	fmt.Println("outdir:", outdir)
	fmt.Println("sign:", sign)
	fmt.Println("key:", key)
	CodecLua(indir, outdir, sign, key)
}


좋은 웹페이지 즐겨찾기