27 มี.ค. 2556

สร้าง PHP Extension

ให้อ่าน http://devzone.zend.com/303/extension-writing-part-i-introduction-to-php-and-zend/ คู่ไปด้วย
แต่ในบทความนี้จะไม่ใช้ phpize + m4 เพื่อ build extension

*เฉพาะกรณีที่ใช้  Visual Studio + Visual GDB

ลง php-devel เพื่อ ใช้ libphp5.so
yum install php-devel
เพื่อให้มัน ใช้ใน *nix ได้ จะต้อง define ตอนเราใช้ std function มันจะได้ไม่เผลอไปใช้ ของ Visual Studio

#ifdef _MSC_VER

#define _X86_ 1

#define _HAVE_STDC 1

#define __GNUC__ 1  //<-----*

- php_tcg.h
#pragma once 

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"

#ifdef DEBUG

#endif

-flags.mak x86
INCLUDE_DIRS := /usr/include/php /usr/include/php/Zend /usr/include/php/main /usr/include/php/TSRM
LIBRARY_DIRS := /usr/lib/httpd/modules/ 
LIBRARY_NAMES := libphp5.so
-flags.mak x64
INCLUDE_DIRS := /usr/include/php /usr/include/php/Zend /usr/include/php/main /usr/include/php/TSRM
LIBRARY_DIRS := /usr/lib64/httpd/modules/ 
LIBRARY_NAMES := libphp5.so
-flags.mak ถ้าใช้ GCC compile *
CFLAGS := -ggdb -ffunction-sections -fPIC 

-php_tcg.cpp
//--predefine function
PHP_MINIT_FUNCTION(php_tcg);
PHP_MSHUTDOWN_FUNCTION(php_tcg);
PHP_RINIT_FUNCTION(php_tcg);
PHP_RSHUTDOWN_FUNCTION(php_tcg);
PHP_FUNCTION(tcg_init);
PHP_FUNCTION(tcg_test);

// list of custom PHP functions provided by this extension
// set {NULL, NULL, NULL} as the last record to mark the end of list
static zend_function_entry tcg_functions[] = 
{
 PHP_FE(tcg_dll_gen, NULL)
 PHP_FE(tcg_init, NULL)
 {NULL, NULL, NULL}
};


zend_module_entry php_tcg_module_entry = 
{
#if ZEND_MODULE_API_NO >= 20010901
 STANDARD_MODULE_HEADER,
#endif
 PHP_MY_EXTENSION_EXTNAME,
 tcg_functions,
 PHP_MINIT(php_tcg), 
 PHP_MSHUTDOWN(php_tcg),
 PHP_RINIT(php_tcg), 
 PHP_RSHUTDOWN(php_tcg),
 NULL, // name of the MINFO function or NULL if not applicable
#if ZEND_MODULE_API_NO >= 20010901
 PHP_MY_EXTENSION_VERSION,
#endif
 STANDARD_MODULE_PROPERTIES
};

PHP_INI_BEGIN()
        //ลอง config ใน php.ini
        //[php_tcg]
        //config_string_1 = "/var/www";
        //config_numeric = 1;
        PHP_INI_ENTRY("php_tcg.config_string_1", "/var/www", PHP_INI_ALL, NULL)
 PHP_INI_ENTRY("php_tcg.config_numeric", "1" , PHP_INI_ALL, NULL)
PHP_INI_END()

PHP_MINIT_FUNCTION(php_tcg)
{
 REGISTER_INI_ENTRIES();
 return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(php_tcg)
{
 UNREGISTER_INI_ENTRIES();
 return SUCCESS;
}

PHP_RINIT_FUNCTION(php_tcg)
{
 return SUCCESS;
}

PHP_RSHUTDOWN_FUNCTION(php_tcg)
{
 return SUCCESS;
}

ZEND_GET_MODULE(php_tcg)

PHP_FUNCTION(tcg_init)
{
        //function test init - check path ว่ามีอยู่จริง
 struct stat buf;
 int i = stat ( INI_STR("php_tcg.config_string_1") , &buf );
 if ( i != 0 )
 {
  php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP_TCG : Invalid path.");
  RETURN_FALSE;
 }
 RETURN_TRUE;
}

PHP_FUNCTION(tcg_test)
{ 
        //function test - รับ parameter เป็น string
        //อย่าลืม #include sys/stat ด้วย
        //ดู เพิ่มที่ http://devzone.zend.com/317/extension-writing-part-ii-parameters-arrays-and-zvals/
 char *username;
 int username_len;
 //get username
 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &username, &username_len) == FAILURE) 
 {
  php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP_TCG : Invalid username param.");
  RETURN_FALSE;
 }
        //ลอง config แบบ bool
       bool _config_bool = INI_BOOL("php_tcg.config_numeric");
       if( _config_bool )
       {
                        //return เป็น array แบบ assoc
                        array_init(return_value);
                        add_assoc_string(return_value, "username", username ,1 );
                        add_assoc_long(return_value, "abc", 200);
                        add_assoc_string(return_value , "str" , "ลองๆ" , 1);
                        RETURN_ZVAL(return_value,1,0);
       } 
       else
       {
                        //return เป็น string
                        RETURN_STRING("Hello World", 1);
       }
}

-test.php
if (tcg_init())
                {
                    $ret_arr = tcg_test('abc');
                    if ($ret_arr != FALSE)
                    {
                        var_dump($ret_arr);
                    }
}

C(Snippet) - mysql AES_Encrypt/AES_Decrypt

Code ในภาษา C  ที่ไว้คุยกับ AES_Encrypt/AES_Decrypt  ของ Mysql

- Mysql Query ใน Codeigniter model
 function aes_encrypt($data,$key)  
   {  
     $sql = "SELECT AES_ENCRYPT(?,?) AS enc_data ;";  
     $query = $this-&gt;db-&gt;query( $sql , array($data,$key));  
     if ($query-&gt;num_rows() &gt;= 1)  
     {  
       $row = $query-&gt;row();  
       return $row-&gt;enc_data;  
     }  
     return NULL;  
   }  
   function aes_decrypt($data,$key)  
   {  
     $sql = "SELECT AES_DECRYPT(?,?) AS dec_data ;";  
     $query = $this-&gt;db-&gt;query( $sql , array($data,$key));  
     if ($query-&gt;num_rows() &gt;= 1)  
     {  
       $row = $query-&gt;row();  
       return $row-&gt;dec_data;  
     }  
     return NULL;  
   }  

- C++ ใช้ CryptoPP Library
 //Rijndael  
 //128bit  
 //Mode: ECB  
 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1  
 #include "cryptlib.h"  
 #include "aes.h"  
 #include "channels.h"  
 #include "files.h"  
 #include "modes.h"  
 #include "rng.h"  
 #include "default.h"  
 //------------  
  byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ];  
  ZeroMemory( key, CryptoPP::AES::DEFAULT_KEYLENGTH );  
  ZeroMemory( iv, CryptoPP::AES::BLOCKSIZE );  
     //Key example = 0000000000000000  
     memcpy(key,"0000000000000000",CryptoPP::AES::DEFAULT_KEYLENGTH);  
  CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);  
  CryptoPP::ECB_Mode_ExternalCipher::Encryption ecbEncryption( aesEncryption, iv );  
     std::string _plaintext = "";  
  std::string _encrypt;  
     CryptoPP::StringSource( _plaintext , true, new CryptoPP::StreamTransformationFilter( ecbEncryption, new CryptoPP::StringSink( _encrypt) ) );   

อ่านเพิ่มโหมดอื่นที่ไม่ใช่ ECB http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

3 มี.ค. 2556

การย้ายที่ Fallback Location ของ Visual Studio




เพราะ Project ภาษา C/C++ มัน generate ไฟล์ dataabase มาใหญ่มากมาย  บางทีเราใช้ Dropbox sync งาน ระหว่างคอมมัน ก็ เจอไฟล์แบบนี้เข้าไปก็เดี้ยง
ตัวอย่าง ไฟล์




ไฟล์พวกนี้จะอยู่ Folder เดียวกับ project ตัวอย่าง รวมแล้ว 1GiB กว่า !!!

เพราะงั้น จะย้ายมันไปไว้นอก Dropbox ได้ที่  Option ของ Visual Studio


แล้วไฟล์ Fallback ก็จะไม่มีปัญหากับ Dropbox อีกต่อไป

การ Crack วิชวลจีดีบี

โปรแกรมวิชวลจีดีบี เป็นโปรแกรมที่เป็น Plugin สำหรับ Visual Studio ที่สามารถ เขียนโปรแกรม ในสภาพแวดล้อมของ Unix,Android Native C,Firmware ได้ และ ที่สำคัญที่สุด มัน Debug ใน Visual Studio ได้ ด้วย GDB !!!!

แต่ใน Google ไม่มีใคร crack ไว้เลย ก็เลยต้องทำเอง
สำหรับผู้ที่ไม่ถนัดการเขียนโปรแกรมบน Linux และ GDB Command Line ลองมา crack ดูกัน

1. ต้องรู้ IL Assembly นิดหน่อย หาอ่านได้ที่ http://www.codeproject.com/Articles/3778/Introduction-to-IL-Assembly-Language
2. รู้วิธีใช้ .Net reflector
3. อ่าน Code .net ที่มัน obfuscation มา รู้เรื่อง

4. Decompile Code! ด้วย .Net reflector
เริ่ม
-  ตัว Plugin จะ check ว่า
SOFTWARE\Sysprogs\วิชวลจีดีบี\Settings\RegistrationKey มีอยู่ในเครื่องรึปล่าว ถ้ามี จะไป อ่านไฟล์ activation.key ถ้าไม่มี จะไปเช็ค temporary.key เพื่อเข้าระบบ trial 30 วัน
- ระบบ trial 30 วัน จะจับคู่ กับ key ใน registry ที่ชื่อ SOFTWARE\Sysprogs\วิชวลจีดีบี\Settings\FlagsV3 โดยเก็บค่า วันเริ่มต้น ทดลอง trial เอาไว้ แล้ว ใส่ข้อมูลวันเริ่มทดลองใน temporary.key ด้วย สามารถ reset trial 30 วันได้ไม่จำกัดด้วยการ ลบไฟล์ temporary.key แล้ว flagsv3 ใน registry
- ลอง ใส่ RegisterationKey มั่วๆ ใน Registry กลายเป็นว่า มันบอกว่า


License to unknow แต่ไม่สามารถใช้ Function อะไรได้

มัน MessageBox! หา MessageBox ใน Code เจอเพียบ
เริ่มจากอันแรก ra.cs 
ไปดูใน reflector

หา class ra และ method ที่ตรงกับใน code และ ไปดูที่ Plugin - Reflexil
ต้องลบ code ส่วนนี้ออก

จำเป็นต้องรู้ IL Assembly บ้างเพราะไม่งั้นจะลบไม่ถูกที่ * ลบที่เลือกตามภาพ
และ ทำซ้ำกับทุกที่ ที่มี MessageBox ที่เกี่ยวข้องกับการ lock feature ของ โปรแกรม

และเมื่่อทำ ครบหมดแล้วก็ จะใช้ ได้ ทุก Feature ที่ถูก lock
แต่จะยังขาด Feature ที่ให้เลือก ใน Project Wizard ตามภาพ
กลับมาหาใน Code 
ไปเจอตามรูป 
กลับมาดูใน Reflector
แก้ให้ enable ตามรูป

ก็จะใช้ ได้ทุก Feature แล้ว

ปล. อย่าลืม อุดหนุน License จริงของเค้าด้วย เพราะ โปรแกรมเค้ามีประโยชน์จริง 



การ Encrypt ข้อมูลบน Memory ด้วย CryptoPP

ต้อง Gen Key Pair (Public/Private Key) ก่อน มีในตัวอย่าง CryptoPP อยู่แล้ว

//Encrypt

BYTE * _Buff = new BYTE[1024 * 1000];
CryptoPP::ArraySink * _WriteBuffer = new CryptoPP::ArraySink( _Buff,1024 * 1000);

DWORD Test1 = 1;
_WriteBuffer->PutWord32(Test1 );

CryptoPP::FileSource privFile("public_file.key", true, new CryptoPP::HexDecoder);
 CryptoPP::RSAES_OAEP_SHA_Encryptor pub(privFile);
 CryptoPP::RandomPool randPool;
 randPool.IncorporateEntropy((byte *)"_SEED", 1);
 CryptoPP::ArraySource(_Buff,_WriteBuffer->TotalPutLength(), true, new CryptoPP::PK_EncryptorFilter(randPool, pub,  (new  CryptoPP::FileSink("encrypted.dat") )));

//Decrypt

//Start dec
  CryptoPP::FileSource privFile2("private_file.key", true, new CryptoPP::HexDecoder);
  CryptoPP::RSAES_OAEP_SHA_Decryptor priv(privFile2);
  BaseCrypto bc;
  CryptoPP::ByteQueue * _bq = new CryptoPP::ByteQueue();
  CryptoPP::FileSource DataFile("encrypted.dat", true, (new CryptoPP::PK_DecryptorFilter(bc.GlobalRNG(), priv, _bq )));


  CryptoPP::word32 Test1= 0;
  size_t _ret = _bq->GetWord32(Test1); //Test1 = 1

ดูดรูปจาก twitpic ตาม Tag ที่ search

เพื่อนคนนึง  วานให้ลองทำดู  แต่ไม่รู้เรื่องอะไรเกี่ยวกับ Image API ของ twitter เลย เริ่มจาก ไปเจอ twitter client ที่ชื่อ tmhOAuth มันสามารถดูด Timeline แบบ search จาก Tag ที่ต้องการใน twitter ได้

1. ใช้ tmhOAuth ดูด post จาก tag ที่ search
2. เขียน code regex เพื่อ find หา url ของ image ใน แต่ละ post
3*. จากนั้นจึงใช้ curl เปิด เว็บ twitpic  แล้ว regex หา <img> อีกครั้ง จากนั้นค่อย โหลด รูปด้วย curl

code ตัวอย่าง <download>

เพิ่งเจอข้อมูลใหม่ จาก
http://stackoverflow.com/questions/3737034/how-can-i-hotlink-embed-a-twitpic-image
แต่สามารถลดขั้นตอนการ regex ในข้อ 3  
ได้ด้วยวิธี
สมมติรูป มี Url ว่า  http://twitpic.com/xxxxyyyy
ให้ใช้ curl โหลด รูปไปที่ http://twitpic.com/show/full/xxxxyyyy  เลย
แต่ต้องแก้ regex ในข้อสองให้หา เฉพาะ twitpic id