• vim开发环境设置

    日期:2015-11-22 | 分类:编程窥探

    以前习惯用sublime text 阅读/写代码,主要还是因为它的界面风格、代码高亮,个人比较喜欢,但是在平常经常是直接拖文件到sublime text导致开了好多个窗口,而且还在Finder里面先找到文件再去,有时觉得又有些不方便。

    平时开电脑,命令行是肯定也开着的,在命令行下自然是习惯用vim来写代码,因此这次直接给vim设置了下开发环境,把文件浏览器、代码函数显示、自动补全、函数提醒等多个实用功能都添加上去,感觉还不错。

    直接上图,下面是windows上的一份代码,只是用来查看效果的。

  • 无法声明Activity的问题解决

    日期:2015-06-26 | 分类:编程窥探

    今天在编译个Andorid项目,发现可以正常编译,但一运行就提示 主activity 不存在,后来发现java源码压根就没编译进去。

    解决方法:设置src目录为源码根目录即可。

  • android studio 编译问题

    日期:2014-06-15 | 分类:编程窥探

    以编译android程序时经常会碰到“cannot resolve symbol 'R'”,偶而还会连同一些style相关的xml出现找不到资源的情况,以前也遇到过,但因为缺乏记录,导致又重蹈覆辙,浪费了不少时间,因此这里备忘下。

    解决方法:这种情况部分可能是由于SDK编译版本不对应导致的,特别是从别人拿过来导入的项目,此时可以打开 "File" => "Programe Structure",更改”compile sdk version"与“build tool version”相同或相近,有此方法试试,然后再重新编译。

  • 作者:Sven Taute
    译者:riusksk(泉哥:http://riusksk.blogbus.com)

    由于JavaScript的动态特性,用它来混淆exploit代码很是容易。由于JavaScript是一种解释语言,网站也提供源代码给用户,因 此,Javascript混淆代码的功能常常被用于保护源代码,以防止被复制粘贴,同时保护开发者的知识产权。在过去几年,用于混淆攻击代码的算法已经被 大大改进了。再加上商业工具的运用,甚至已经开发出可伪装(隐含经空白字符格式化的payload)的混淆器。

    检测恶意Javascript的问题
    对于经动态混淆的代码,利用已知特征码的方法是检测不到的,因此经混淆处理后的代码就无法识别出是恶意代码。对此,反病毒扫描器需要有一个良好的仿真引 擎,以识别出经解压后脚本的运行行为。既而,这也就引发了一场攻击者与安全软件厂商之间的争夺战。混淆代码是为了保护源代码的知识产权,同时也可用于更好 地隐藏exploit特征码,它们似乎有许多共性:它们都被复杂化处理,以隐藏真实代码,防止被人们或检测软件识别。
    基于特征码的检测方法一经失效,反病毒引擎就必须分析和仿真JavaScript,直到识别出脚本的真实功能,以达到检测恶意代码的目的。如上所 述,JavaScript是一种可用多种方法来隐藏代码的语言,它支持各类元编程(metaprogramming)(译注:元编程是指某类计算机程序的 编写,这类计算机程序编写或者操纵其它程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作。多数情况下,与手工编写全部代码相 比,程序员可以获得更高的工作效率, 或者给与程序更大的灵活度去处理新的情形而无需重新编译),这意味着代码可实现自修改,并创建出新代码。先加密字符 串,然后用eval()函数来执行也是一种众所周知的方法。由于代码必须能够自我运行,因此JavaScript混淆器集成了KEY和经大量混淆算法实现 的解密程序。

    JavaScript代码压缩器的不同功能和限制
    从攻击者的角度来看,存在一个优势,那就是网站开发者在大多JavaScript压缩器中并未考虑到因素:时间因素。在正当网站上经混淆的代码必须执行得 够快,即使是未经压缩的代码也应如此。然而,从攻击者的角度来看,我们确实还有一些时间可以拿来利用,但如果exploit的执行是在毫秒或2秒内完成 的,这就无所谓了,因为大多受害者并不会注意到它,甚至不会在当时打开任务管理器杀死进程。然而反病毒扫描器必须像网站开发者一样以相同的方式来处理 Javascript,它的执行不能比未扫描时花费明显过多的时间,最好是1秒的十分之一。

    利用时间因素
    为了利用时间因素,代码压缩器需要创建出不会在一定时间跨度(timespan)内被分析出来的代码。由于这技术不应过于复杂,因此它必须以某种方式来执 行,并且这种方式要求在短时间内不会分析出代码,所以最好的解决方案就是加密payload。对比现在流行的代码压缩器,它们均没有满足加密 payload的所有关键要求,自然而然地,也就不可能在合理的时间内进行解密。这不仅要求让反病毒扫描器无法查看payload,攻击者的浏览器也不 能。如前所述,由于反病毒扫描器的快速分析,因此在攻击者浏览器上的执行时间相对比较紧迫。然而也并非都是如此,我们可以创建一个加载器,用于暴力搜索访 问payload的KEY,然后选用一个在数秒内可破解的KEY。最后导致反病毒引擎超时,但此时payload已经在浏览器中运行了。在当今浏览器里都 拥有高优化的JavaScript引擎,运行暴破算法的速度很快,这给我们提供了很大的优势。
    ……

     

    Attached Files
    File Type: doc 利用强迫超时规避JavaScript Exploit 特征码检测.doc (607.5 KB)
  • 作者:Shawn (L. Spiro) Wilcoxen
    译者:riusksk(泉哥)

    前言
    逃避反外挂系统的检测是当今新生游戏黑客最大的障碍,而存活最久的逃避方法当属DLL注入。在外面流传的黑客技术/工具是最容易被封杀的,这仅在与目标游 戏进行频繁交互的系统函数上挂钩即可实现。本文涵盖了这些技术及工具绕过检测的方法,仅通过向目标进程注入DLL来避免调用挂钩的系统函数,进而使这些黑 客工具可以访问任何目标进程,如果直接调用的话就可能会被反外挂系统发现,进而被查杀。在本文中有两份独立代码:一份是用于注入到游戏进程的DLL文件, 一份是与DLL交互的工具,主要用于秘密获取目标进程的相关信息。
    ……

     

    Attached Files
    File Type: rar 决战反外挂系统之秘密通讯原理.rar (1.88 MB)
  • 《c primer plus》一书看了几个月才看完,由于实习的原因,拖了很久,昨晚才刚看完,顺便把坚持写的笔记共享出来,里面很多内容除了自己的一点心得外,都是书上的 东西,或者网上搜索到的一点资料,对C语言有兴趣的朋友可以看下,算是对此书的缩写版,哈哈……

    下载:

    http://unpack.cn/attachment.php?aid=MzU4NzN8OTNmMTU2Y2R8MTI3NzcyNjY1OXw4YWI1b0JTM0ZiNloxa2tmSmZqNG1uM1NLS1NSZFh0MVo2azRvM3FBTURZMnhaSQ%3D%3D

    http://bbs.pediy.com/attachment.php?attachmentid=45024&stc=1&d=1277726813
    http://bbs.isbase.net/attachment.php?aid=NTA2OXwwMTkzOTVmNXwxMjc3NzI3MjUwfDJkY2JmQys3VFIwaURIL3VWMVRBV24vY3hsMFRGKzlNZG5jeXBzbEhoNnppS25Z

  • 180. 树类型的支持函数:
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "tree.h"

    /*局部数据类型 */
    typedef struct pair {
        Node * parent;
        Node * child;
    } Pair;

    /*局部函数原型 */
    static Node * MakeNode(const Item * pi);
    static bool ToLeft(const Item * i1, const Item * i2);
    static bool ToRight(const Item * i1, const Item * i2);
    static void AddNode (Node * new_node, Node * root);
    static void InOrder(const Node * root, void (* pfun)(Item item));
    static Pair SeekItem(const Item * pi, const Tree * ptree);
    static void DeleteNode(Node **ptr);
    static void DeleteAllNodes(Node * ptr);

    /* 函数定义 */
    void InitializeTree(Tree * ptree)
    {
        ptree->root = NULL;
        ptree->size = 0;
    }

    bool TreeIsEmpty(const Tree * ptree)
    {
        if (ptree->root == NULL)
            return true;
        else
            return false;
    }

    bool TreeIsFull(const Tree * ptree)
    {
        if (ptree->size == MAXITEMS)
            return true;
        else
            return false;
    }

    int TreeItemCount(const Tree * ptree)
    {
        return ptree->size;
    }

    bool AddItem(const Item * pi, Tree * ptree)        
    {
        Node * new_node;

        if  (TreeIsFull(ptree))
        {
            fprintf(stderr,"Tree is full\n");
            return false;             /* 提前返回          */
        }
        if (SeekItem(pi, ptree).child != NULL)
        {
            fprintf(stderr, "Attempted to add duplicate item\n");
            return false;             /* 提前返回           */
        }
        new_node = MakeNode(pi);      /* 指向新节点    */
        if (new_node == NULL)
        {
            fprintf(stderr, "Couldn't create node\n");
            return false;             /* 提前返回           */
        }
        /* 成功创建了一个新节点 */
        ptree->size++;

        if (ptree->root == NULL)      /* 情况1:树为空树 */
            ptree->root = new_node;   /* 新节点即为树的根节点  */
        else                          /* 情况2:树非空      */
            AddNode(new_node,ptree->root); /* 把新节点添加到树中  */
       
        return true;                  /* 成功返回      */
    }

    bool InTree(const Item * pi, const Tree * ptree)
    {
        return (SeekItem(pi, ptree).child == NULL) ? false : true;
    }

    bool DeleteItem(const Item * pi, Tree * ptree)
    {
        Pair look;
        
        look = SeekItem(pi, ptree);
        if (look.child == NULL)
            return false;
     
        if (look.parent == NULL)      /* 删除根项目       */
            DeleteNode(&ptree->root);
        else if (look.parent->left == look.child)
            DeleteNode(&look.parent->left);
        else
            DeleteNode(&look.parent->right);
        ptree->size--;

        return true;
    }

    void Traverse (const Tree * ptree, void (* pfun)(Item item))
    {

        if (ptree != NULL)
            InOrder(ptree->root, pfun);
    }

    void DeleteAll(Tree * ptree)
    {
        if (ptree != NULL)
            DeleteAllNodes(ptree->root);
        ptree->root = NULL;
        ptree->size = 0;
    }


    /* 局部函数 */
    static void InOrder(const Node * root, void (* pfun)(Item item))
    {
        if (root != NULL)
        {
            InOrder(root->left, pfun);
            (*pfun)(root->item);
            InOrder(root->right, pfun);
        }
    }

    static void DeleteAllNodes(Node * root)
    {
        Node * pright;

        if (root != NULL)
        {
            pright = root->right;
            DeleteAllNodes(root->left);
            free(root);
            DeleteAllNodes(pright);
        }
    }

    static void AddNode (Node * new_node, Node * root)
    {
        if (ToLeft(&new_node->item, &root->item))
        {
            if (root->left == NULL)      /* 空子树      */
                root->left = new_node;   /* 因此把节点添加到此处    */
            else
                AddNode(new_node, root->left);/*否则处理该子树*/
        }
        else if (ToRight(&new_node->item, &root->item))
        {
            if (root->right == NULL)
                root->right = new_node;
            else
                AddNode(new_node, root->right);
        }
        else                         /* 不应含有相同的项目 */
        {
            fprintf(stderr,"location error in AddNode()\n");
            exit(1);
        }
    }

    static bool ToLeft(const Item * i1, const Item * i2)
    {
        int comp1;

        if ((comp1 = strcmp(i1->petname, i2->petname)) < 0)
            return true;
        else if (comp1 == 0 && strcmp(i1->petkind, i2->petkind) < 0 )
            return true;
        else
            return false;
    }

    static bool ToRight(const Item * i1, const Item * i2)
    {
        int comp1;

        if ((comp1 = strcmp(i1->petname, i2->petname)) > 0)
            return true;
        else if (comp1 == 0 && strcmp(i1->petkind, i2->petkind) > 0 )
            return true;
        else
            return false;
    }

    static Node * MakeNode(const Item * pi)
    {
        Node * new_node;

        new_node = (Node *) malloc(sizeof(Node));
        if (new_node != NULL)
        {
            new_node->item = *pi;
            new_node->left = NULL;
            new_node->right = NULL;
        }
        
        return new_node;
    }

    static Pair SeekItem(const Item * pi, const Tree * ptree)
    {
        Pair look;
        look.parent = NULL;
        look.child = ptree->root;

        if (look.child == NULL)
            return look;                        /* 提前返回  */
     
        while (look.child != NULL)
        {
            if (ToLeft(pi, &(look.child->item)))
            {
                look.parent = look.child;
                look.child = look.child->left;
            }
            else if (ToRight(pi, &(look.child->item)))
            {
                look.parent = look.child;
                look.child = look.child->right;
            }
            else       /*如果前面两种情况都不满足,必定为相等的情况   */
                break; /* look.child 是目标项目节点的地址 */
        }
     
        return look;                       /*成功返回  */
    }

    static void DeleteNode(Node **ptr)
    /* ptr 是指向目标节点的父节点指针成员的地址  */
    {
        Node * temp;

        puts((*ptr)->item.petname);
        if ( (*ptr)->left == NULL)
        {
            temp = *ptr;
            *ptr = (*ptr)->right;
            free(temp);
        }
        else if ( (*ptr)->right == NULL)
        {
            temp = *ptr;
            *ptr = (*ptr)->left;
            free(temp);
        }
        else    /* 被删除节点有两个子节点 */
        {
            /*找到右子树的依附位置 */
            for (temp = (*ptr)->left; temp->right != NULL;
                    temp = temp->right)
                continue;
            temp->right = (*ptr)->right;
            temp = *ptr;
            *ptr =(*ptr)->left;
            free(temp);
        }
    }

    181. 二叉树搜索只在满员(或者称为平衡)时效率最高,而搜索不平衡二叉树时并不比顺序搜索链表来得更快。

    182. AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是Olog n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

     

  • 172. 为类型的属性和可对类型执行的操作提供一个抽象的描述,这样一种正式的抽象描述被称为抽象数据类型(ADT)。

    173. 把实现和最终接口相隔离的做法对于大型编程工程来说尤其有用,这称为数据隐藏,因为详细的数据表示对终端用户是不可见的。

    174. 用抽象数据类型方法进行C语言编程包含下面三个步骤:

    1. 以抽象、通用的方式描述一个类型,包括其操作。

    2. 设计一个函数接口来表示这种新类型。

    3. 编写具体代码以实现这个接口。

    175. 队列是具有两大特殊属性的列表。第一,新的项目只能被添加到列表结尾处;第二,项目只能从列表开始处被移除,它是一种“先进先出”的数据形式。

    176.

    向数组插入一个元素,必须移动其他元素以便安插新元素,新元素离数组头越近,要移动的元素越多。而向链表插入一个节点,只需分配两个指针值。类似地,从数组中删除一个元素要重新安置大量元素,而从链表中删除一个节点只需重新设置一个指针并释放被删除节点使用的内存。对数组来说,可以用数组索引直接访问任意元素,这被称为随机访问。对链表来说,必须从列表头开始,逐个节点地移动到所需的节点处,这叫做顺序访问。数组也可以顺序访问,只要在数组中按顺序使用数组索引递增即可。

    177. 折半搜索法:n次比较能处理具有2n-1个成员的数组。

    178. 二叉搜索树:一种既支持频繁地插入和删除元素又支持频繁搜索的数据类型,链表和数组都不是针对这个目标的理想选择。

    179. 删除节点:

     

  • 168.使用可变个数的参数:

    #include <stdio.h>

    #include <stdarg.h>

    double sum (int, ...);

    int main (void)

    {

               double s,t;

               s = sum (3, 1.1, 2.5, 13.3);

               t = sum(6, 1.1, 2.1, 13.1, 4.2, 5.1, 6.1);

               printf("return value for sum (3, 1.1, 2.5, 13.3):%g\n",s);

               printf("return value for sum (6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1):%g\n",t);

               return 0;

    }

    double sum (int lim, ...)

    {

               va_list ap;            // 声明用于存放参数的变量

               double tot = 0;

               int i;

               va_start (ap, lim);          //把ap初始化为参数列表

               for ( i=0; i<lim; i++)

                        tot += va_arg (ap, double);    //访问参数列表中的每一个项目

               va_end (ap);        //清理工作

               return tot;

    }

    运行结果:

    return value for sum (3, 1.1, 2.5, 13.3):16.9

    return value for sum (6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1):31.7

    169.

    170.

    171. 使用结构链表:

    #include "stdio.h"

    #include "stdlib.h"

    #include "string.h"

    #define TSIZE 45


    struct film {

    char title [TSIZE];

    int rating;

    struct film * next;

    };


    int main (void)

    {

    struct film * head = NULL;

    struct film * prev, * current;

    char input[TSIZE];


    puts("enter first movie title:");

    while(gets(input)!=NULL && input[0] != '\0')

    {

               current = (struct film *) malloc(sizeof(struct film));

               if (head == NULL)

                        head = current;

               else

                        prev->next = current;

               current->next = NULL;

               strcpy(current->title,input);

               puts("enter your rating:");

               scanf("%d",&current->rating);

               while(getchar()!= '\n')

                        continue;

               puts("enter next movie title (emtpy line to stop):");

               prev = current;

    }

    if(head == NULL)

               printf("no data entered.");

    else

               printf("here is the movie list:\n");

    current = head;

    while (current != NULL)

    {

               printf("Movie:%s Rating:%d\n",current->title,current->rating);

               current = current->next;

    }


    current = head;

    while (current!= NULL)

    {

               free(current);

               current = current->next;

    }

    printf("bye!\n");

    return 0;

    }

  • 166. 头文件assert.h支持的诊断库是设计用于辅助调试程序的小型库。它由宏assert()构成,该宏接受整数表达式作为参数。如果表达式值为假(非 零),宏assert()向标准错误流(stderr)写一条错误消息并调用abort()函数以终止程序(在头文件stdlib.h中定义abort()函数的原型)。assert()宏的作用为:标识出程序中某个条件应为真的关键位置,并在条件为假 时用assert()语句终止该程序。通常,assert()的参数为关系或逻辑表达式。如果assert()终止程序,那么它首先会显示失败的判断、包含该判断的文件名和 行号。示例代码:

    #include <stdio.h>

    #include "math.h"

    #include "assert.h"

    int main()

    {

    double x,y,z;

    puts("enter a pair of numbers:");

    while(scanf("%lf%lf",&x,&y) == 2

               && (x!=0 || y!=0))

    {

               z = x*x - y*y;

               assert(z >= 0);     //这里并不是声称z>=0,而是声称z>=0这个条件没有得到满足,

                                                    //相当于if(z<0) abort();

               printf("answer is %f\n",sqrt(z));

               puts("next pair of numbers:");

    }

     

    return 0;

    }

    运行结果:

    如果在assert.h前定义:

    #define NDEBUG

    那么编译器将禁用文件中所有的assert()语句,比如:

    enter a pair of numbers:

    5 6

    answer is -1.#IND00

    next pair of numbers:

    167. string.h库中的memcpy()和memmove():

    函数原型:

    void *memcpy(void * restrict s1,const void 8 restrict s2, size_t n);

    void *memmove(void *s1,const void *s2, size_t n);

    两个函数均是从s2指向的位置复制n字节数据到s1指向的 位置,且均返回s1的值。两者间的差别由关键字restrict造成,即memcpy()可以假定两个内存区域之间没有重叠。memmove()函数则不作这个假定,因此,复制过程类似于首先将所有字节复制 到一个临时缓冲区,然后再复制到最终目的地。如果两个区域存在重叠时使用memcpy() 时,其行为是不可预知的,即可能正常工作,也可能失败。示例代码:

    #include <stdio.h>

    #include "string.h"

    #include "stdlib.h"

    #define SIZE 4

    void show_array (const int ar[],int n);

     

    int main()

    {

    int value[SIZE]={1,2,3,4};

    int target[SIZE];

    double curious[SIZE/2] = {1.0, 2.0};

     

    puts("memcpy() used:");

    puts("values (original data):");

    show_array(value,SIZE);

    memcpy(target,value,SIZE*sizeof(int));

    puts("target (copy of values):");

    show_array(target,SIZE);

     

    puts("using memmove() with overlapping ranges:");

    memmove(value+2,value,(SIZE/2)*sizeof(double));            // 可能会导致崩溃,实际中不推荐使用

    show_array(value,SIZE);

     

    puts("using memcpy()to copy double to int:");

    memcpy(target,curious,(SIZE/2)*sizeof(double));

    puts("tartget -- 2 doubles into 4 int positions:");

    show_array(target,SIZE);

     

    return 0;

    }

     

    void show_array(const int ar[],int n)

    {

    int i;

     

    for(i=0;i<n;i++)

               printf("%d ",ar[i]);

    putchar('\n');

    }

    运行结果:

    memcpy() used:

    values (original data):

    1 2 3 4

    target (copy of values):

    1 2 3 4

    using memmove() with overlapping ranges:

    2 3 4 4

    using memcpy()to copy double to int:

    tartget -- 2 doubles into 4 int positions:

    0 1072693248 0 1073741824